summary refs log tree commit diff stats
path: root/lisp/dawn.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/dawn.el')
-rw-r--r--lisp/dawn.el84
1 files changed, 84 insertions, 0 deletions
diff --git a/lisp/dawn.el b/lisp/dawn.el new file mode 100644 index 0000000..806c422 --- /dev/null +++ b/lisp/dawn.el
@@ -0,0 +1,84 @@
1;;; dawn.el --- Do things at dawn (and dusk) -*- lexical-binding: t; -*-
2
3;;; Commentary:
4
5;; There is also circadian.el, but it doesn't quite work for me.
6;; This code comes mostly from https://gnu.xyz/auto_theme.html, but also
7;; somewhere else (which I've forgotten) and my own brain :)
8
9;;; Code:
10
11(require 'calendar)
12(require 'cl-lib)
13(require 'solar)
14
15(defvar dawn--dawn-timer nil
16 "Timer for dawn-command.")
17
18(defvar dawn--dusk-timer nil
19 "Timer for dusk-command.")
20
21(defvar dawn--reset-timer nil
22 "Timer to reset dawn at midnight.")
23
24(defun dawn-encode-time (f)
25 "Encode fractional time F."
26 (let ((hhmm (cl-floor f))
27 (date (cdddr (decode-time))))
28 (encode-time
29 (append (list 0
30 (round (* 60 (cadr hhmm)))
31 (car hhmm)
32 )
33 date))))
34
35(defun dawn-midnight ()
36 "Return the time of the /next/ midnight."
37 (let ((date (cdddr (decode-time))))
38 (encode-time
39 (append (list 0 0 0 (1+ (car date))) (cdr date)))))
40
41(defun dawn-sunrise ()
42 "Return the time of today's sunrise."
43 (dawn-encode-time (caar (solar-sunrise-sunset (calendar-current-date)))))
44
45(defun dawn-sunset ()
46 "Return the time of today's sunset."
47 (dawn-encode-time (caadr (solar-sunrise-sunset (calendar-current-date)))))
48
49(defun dawn-schedule (dawn-command dusk-command)
50 "Run DAWN-COMMAND at sunrise, and DUSK-COMMAND at dusk.
51RESET is an argument for internal use."
52 (when (or (null calendar-longitude)
53 (null calendar-latitude))
54 (user-error "`dawn' won't work without setting %s!"
55 (cond ((and (null calendar-longitude)
56 (null calendar-latitude))
57 "`calendar-longitude' and `calendar-latitude'")
58 ((null calendar-longitude)
59 "`calendar-longitude'")
60 ((null calendar-latitude)
61 "`calendar-latitude'"))))
62 (let ((dawn (dawn-sunrise))
63 (dusk (dawn-sunset)))
64 (cond
65 ((time-less-p nil dawn)
66 ;; If it isn't dawn yet, it's still dark. Run DUSK-COMMAND and schedule
67 ;; DAWN-COMMAND and DUSK-COMMAND for later.
68 (funcall dusk-command)
69 (run-at-time dawn nil dawn-command)
70 (run-at-time dusk nil dusk-command))
71 ((time-less-p nil dusk)
72 ;; If it isn't dusk yet, it's still light. Run DAWN-COMMAND and schedule
73 ;; DUSK-COMMAND.
74 (funcall dawn-command)
75 (run-at-time dusk nil dusk-command))
76 (t ;; Otherwise, it's past dusk, so run DUSK-COMMAND.
77 (funcall dusk-command)))
78 ;; Schedule a reset at midnight, to re-calculate dawn/dusk times.
79 ;(unless reset)
80 (run-at-time (dawn-midnight) nil
81 #'dawn-schedule dawn-command dusk-command)))
82
83(provide 'dawn)
84;;; dawn.el ends here