mac bookのバッテリー状態をはてなグラフに記録してみよう
[2014.08.10追記]
記事が古く、Mavericks(ruby2.0)で動かない(gemのHatena::API::Graphが動かない)
はてなグラフAPIも2014年3月にOAuth認証以外は受け付けなくなって、グラフデータが追加できない、などぼろぼろなので、上記に対処したコードを投稿しました。
mac bookのバッテリー状態をはてなグラフに記録してみよう(OS X 10.9 Mavericks対応版) - mac日記
[追記ここまで]
だいぶ前から、このネタやってたんですけどね。。。
やっとコードを晒せる状態になったというか。
最初に、やりたいことができることを確認しちゃったら、そのあと、ほったらかしにしてました。
まともに動くようにコードを整理したので、公開してみたいと思います。
なにか新しい発明、という訳ではないし、だれでもささっとかけちゃうコードですが、、。
(rubyでがっつりコード書いたことないんで、たぶん文化に沿ってないところとかはあると思うけど、
変なところあったら指摘してもらえるとうれしいです。)
gem の Hatena::API::Graph パッケージを使っているので、
はてなグラフapiとは - はてなキーワードを参考に
インストールしておく必要があります。
あとは、cron にでも登録しておけば、毎日自動ではてなグラフにバッテリーの寿命?を記録していってくれます。
MacBook Pro battery capacity (mAh)
MacBook Pro battery cycle (times)
#!/usr/bin/ruby require 'rubygems' require 'hatena/api/graph' class BatteryLog HATENA_USER = '[はてなのidを書く]' HATENA_PASS = '[はてなのpasswordを書く]' GRAPH_NAME_CAPA = 'macbook pro battery capacity (mAh)' GRAPH_NAME_CYCLE = 'macbook pro battery cycle time' BATTERY_LOG = 'battery.log' DEBUG_LOG = 'battery.dbg.log' LOG_PATH = File.dirname(__FILE__) def run logging post end def logging if logged? _debug("no write log") return end capa, cycle = get_status _logging(Time.new, capa, cycle) _debug("write log") end def logged? Date.today == latest_log_date end def _logging(time, capa, cycle) l = sprintf("%s,%d,%d,*", time.strftime("%Y/%m/%d %H:%M:%S"), capa, cycle) io = open(battery_log(), "a") io.puts(l) io.close end def decode(l) if /(\d{4}\/\d{2}\/\d{2}).+?,(\d+),(\d+)/ =~ l [Date.parse($1), $2, $3] else nil end end def post temp_file_name = battery_log() + ".tmp"; r = open(battery_log(), "r") w = open(temp_file_name, "w") while l = r.gets l.chomp! if !posted?(l) if _post(l) l = posted!(l) end end w.puts(l) end r.close w.close File.rename(temp_file_name, battery_log()) end def _post(l) date, capa, cycle = decode(l) if date post_hatena(date, capa, cycle) else _debug("failure decode [" + l + "]") end end def posted?(l) /-$/ =~ l end def posted!(l) l.sub(/,\*$/, ",-") end def get_status s = eval(`/usr/sbin/ioreg -w0 -l | grep LegacyBatteryInfo`.gsub(/=/, '=>').gsub(/^.*\{/, '{')) capa = s["Capacity"] cycle = s["Cycle Count"] if (capa && cycle) [capa, cycle] else [-1, -1] end end def latest_log_date if (!File.file?(battery_log())) return nil; end log = battery_log() tail = `tail -n1 #{log}` if /(\d{4}\/\d{2}\/\d{2})/ =~ tail Date.parse($1) else nil end end def post_hatena(_date, capa, cycle) _debug(sprintf("post to hatena graph ... (%s, %d, %d)", _date, capa, cycle)) ret = true graph = Hatena::API::Graph.new(HATENA_USER, HATENA_PASS) begin graph.post_data(GRAPH_NAME_CAPA, :date => _date, :value => capa) graph.post_data(GRAPH_NAME_CYCLE, :date => _date, :value => cycle) rescue ret = false end _debug(ret ? "success" : "failure") ret end def _debug(l) if debug_log().size > 0 io = open(debug_log(), "a") io.puts(Time.new.strftime("%Y/%m/%d %H:%M:%S") + " " + l) io.close end end def battery_log() LOG_PATH + "/" + BATTERY_LOG end def debug_log() LOG_PATH + "/" + DEBUG_LOG end end BatteryLog.new.run