Skip to content

Instantly share code, notes, and snippets.

@miyamuko
Created March 23, 2011 02:21
Show Gist options
  • Save miyamuko/882497 to your computer and use it in GitHub Desktop.
Save miyamuko/882497 to your computer and use it in GitHub Desktop.
東京電力の電力供給状況を #xyzzy のモードラインに表示
; -*- mode: lisp; package: power-usage -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; 続きは GitHub で。
;; https://github.com/miyamuko/power-usage
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; http://tepco-usage-api.appspot.com/ から取得した電力消費量を
;; xyzzy のモードラインに表示します。
;;
;; Usage:
;;
;; 1. *power-usage-update-interval* で監視間隔を設定
;; (デフォルトは 1 時間)
;; 2. *power-usage-mode-line-format* でモードラインをお好みで設定
;; 3. M-x power-usage-mode でモードラインに表示
;;
(in-package :user)
(eval-when (:compile-toplevel :load-toplevel :execute)
(require "xml-http-request")
(require "json")
(unless (find-package :power-usage)
(defpackage :power-usage
(:use :lisp :editor))
(use-package :power-usage :user)
))
(in-package :power-usage)
(export '(*power-usage-api-endpoint*
*power-usage-update-interval*
*power-usage-mode-line-format*
*power-usage-update-hook*
*last-power-usage*
power-usage-mode
update-power-usage
get-power-usage
start-power-usage-watcher
stop-power-usage-watcher
))
(defvar *power-usage-api-endpoint* "http://tepco-usage-api.appspot.com/latest.json"
"東京電力電力供給状況 API の URL")
(defvar *power-usage-update-interval* (* 10 60)
"自動更新の間隔 (デフォルト: 1 時間)")
(defvar *power-usage-mode-line-format* "~A/~A万kW:~D%~:[~;:計画停電実施中~]"
"モードラインに表示するフォーマット (引数は消費電力、最大電力、使用率、計画停電実施中かどうか)")
(defvar *power-usage-update-hook* nil
"自動更新時に実行されるフック")
(defparameter *last-power-usage* nil
"最後に取得した電力消費量 (tepco-power 構造体)")
(defvar *power-usage-mode* nil)
(defvar *mode-line* nil)
(defstruct tepco-power
datetime ; 年月日 (ユニバーサルタイム)
entryfor ; この時刻の文字列(UTC)
capacity ; 供給可能最大電力(万kW)
capacity-updated ; 供給可能最大電力が決定された日時(UTC)
usage ; この時刻の消費電力(万kW)
usage-updated ; この消費電力のデータが更新された日時(UTC)
saving-p ; この時刻に計画停電が実施されていれば t
)
(defun get-power-usage ()
(parse-power-usage (xhr:xhr-get *power-usage-api-endpoint*
:nomsg t :since :epoch)))
(defun update-power-usage ()
(xhr:xhr-get-async *power-usage-api-endpoint*
:nomsg t :since :epoch
:onsuccess 'end-update-power-usage))
(defun end-update-power-usage (res)
(setf *last-power-usage* (parse-power-usage res))
(run-hooks '*power-usage-update-hook*))
(defun parse-power-usage (res)
(let ((json (json:json-decode (xhr:xhr-response-text res))))
(macrolet (($ (json key)
`(cdr (assoc ,key ,json :test #'string=))))
(make-tepco-power :datetime (encode-universal-time
0 0 ($ json :hour)
($ json :day) ($ json :month) ($ json :year))
:entryfor ($ json :entryfor)
:capacity ($ json :capacity)
:capacity-updated ($ json :capacity_updated)
:usage ($ json :usage)
:usage-updated ($ json :usage_updated)
:saving-p ($ json :saving)))))
(defun power-usage-status-string (&optional (u *last-power-usage*))
(when u
(format nil *power-usage-mode-line-format*
(tepco-power-usage u)
(tepco-power-capacity u)
(round (* (/ (tepco-power-usage u)
(tepco-power-capacity u))
100.0))
(tepco-power-saving-p u))))
(defun start-power-usage-watcher ()
(interactive)
(stop-power-usage-watcher)
(update-power-usage)
(start-timer *power-usage-update-interval* 'update-power-usage))
(defun stop-power-usage-watcher ()
(interactive)
(stop-timer 'update-power-usage))
(defun update-mode-line-status ()
(interactive)
(setf *mode-line* (power-usage-status-string))
(update-mode-line t))
(add-hook '*power-usage-update-hook* 'update-mode-line-status)
(defun power-usage-mode (&optional (arg nil sv))
(interactive "p")
(ed::toggle-mode '*power-usage-mode* arg sv)
(cond (*power-usage-mode*
(start-power-usage-watcher)
(update-mode-line-status))
(t
(stop-power-usage-watcher)
(update-mode-line t))))
(pushnew '(*power-usage-mode* . *mode-line*) ed:*minor-mode-alist* :key #'car)
(provide "power-usage-mode")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment