普通の腕時計を買うつもりが、スマートウォッチになったわけ

     もう10年以上前から腕時計をする習慣が無くなっていたのですが、携帯電話からスマホに変わってからは胸ポケットに入れられないスマホを鞄から取り出すのが面倒なため腕時計をする機会が多くなっていました。でも今はロードバイク用に買ったアウトドア用のソーラー電波時計しか無いので、一つビジネスにも使えるようなものを買ってみようかと思って「予算10万円台までで購入できる 最強スポーツウオッチ選手権」と銘打った時計雑誌を購入しました。
     雑誌の中ではいろいろ欲しくなる時計は紹介されていたのですが、小さく紹介されていた「Withings Activité」のデザインが気に入ってネットで調べてみるとスマートウォッチというカテゴリーに分類される時計のようです。Apple Watchにもほとんど興味が湧かなかった自分にとっては、すでに世の中にいろいろなスマートウォッチと呼ばれる時計が出回っていることを知って驚きでした。
     そして、

    • サイレントアラーム(音ではなく振動で目覚まし)を体験したい
    • せっかく身に付けるものが増えるなら万歩計の機能も欲しい
    • ちょうど体重計を買い換えようと思っていたので、Withing製品で揃えよう

     というビジネス時計を買うという当初の目的に無かった余計な欲が出てきて、スマホと連携して遊べそうな「Withings Activité」が欲しくなってきました。昔ロードバイクを初めて購入した時にHOLUXのGPSロガーを購入しロードバイクで彼方此方走った記録を後からニヤニヤしながら地図上で記録をなぞっていくのを楽しんでいた時期がありましたが、それに近いものがあるような気がします。自転車乗るのも好きだけど、後からGPSデータを眺めるのも好き。腕時計も好きだけど、付加された遊び機能も好き、みたいな。それに何と言っても「Withings Activité」のデザインやサファイアガラスを使っている点などは時計としての魅力もたっぷりで、スマートウォッチの機能に飽きたとしても長く使っていけそうだと思ったことが購入を決めた大きな理由です(電池を自分で交換できる点もいい)。
     ちなみにGPSロガーはすぐに飽きて使わなくなったのですが、初めて買ったロードバイクは今でもお気に入りで乗り続けています。

    セットアップ完了

     それにしても購入を決めた当初は、自分のように時計を物色していてこの機種を購入するに至った人は珍しいんじゃないかと思っていたのですが、その後もスマートウォッチの情報をネットで漁っているとApple Watchのような如何にも今までの腕時計とは異質のものではなく、見た目は本格的な腕時計のままスマホとの連携機能を持つスタイルのスマートウォッチのほうが主流になる可能性があることを知りました1。時計雑誌で紹介されていたスマートウォッチはこの機種だけだったので、浮いている感じを受けましたが、今後は普通の時計雑誌でスマートウォッチが紹介される機会が増えてくるのかもしれません。
     セットアップはこちらのサイトを参考にしました。

    日毎の睡眠パターン

     上のグラフのように浅い眠りと深い眠りを判別出来るようです。寝起きに「あ〜よく寝た」と感じた時は濃い青のグラフの帯が大きかったので結構正確かもしれません。それと当たり前かもしれませんが朝方トイレに起きた履歴もちゃんと残っていて、いつか自分の記憶にない記録が残っていたりしないかと密かに期待しています(夢遊病か!?)。

    Web APIを使ってみる

     APIが公開されていたので少し触ってみました。Withings API Quickstart Guideと銘打ったサイトの通りwithings用のgemを使えばすぐに自分が登録したデータを取得することが出来ましたが、最新のAPIに対応しているか分からなかったし使い方もよくわからないし、アクセストークンを取得した後はWithingsのAPIドキュメントを見ながら自分でパラメータをセットしていろんなデータの取得を試してみたかったので、特別なgemを使用せずにjsonデータを取得するスクリプトを書いてみました。
     このスクリプトを実行するにはTwitterアプリを作る時なんかと同様にWithingsにアプリを登録してAPI Key、API Secretを取得する必要があります。そしてWithings API のページのFIRST STEPに従って操作し、OAuth認証完了後userid、oauth_token、oauth_token_secretの値を取得してスクリプトにセットしておく必要があります。

    #sleep.rb
    require 'pp'
    require 'openssl'
    require 'time'
    require 'json'
    require 'net/http'
    require 'cgi'
    require 'base64'
    
    BASE_URI='https://wbsapi.withings.net'
    WITHINGS_OAUTH_CONSUMER_KEY='xxxxx'
    WITHINGS_OAUTH_CONSUMER_SECRET='yyyyy'
    
    user_id = 1234567
    oauth_token = "aiueo"
    oauth_token_secret = "iroha"
    
    params = {:action => :get, :userid => 1234567}
    #params = {:action => :getworkouts, :userid => 1234567}
    #params = {:action => :getsummary, :userid => 1234567}
    #params = {:action => :getactivity, :userid => 1234567}
    #params = {:action => :getbyuserid, :userid => 1234567}
    
    url = BASE_URI + '/v2/sleep'
    #url = BASE_URI + '/v2/measure'
    #url = BASE_URI + '/user'
    #url = BASE_URI + '/v2/user'
    
    params.merge!({
                    :oauth_consumer_key => WITHINGS_OAUTH_CONSUMER_KEY,
                    :startdate => Time.parse("2015-08-07 12:00:00").to_i,
                    :enddate => Time.parse("2015-08-08 12:00:00").to_i,
    #                :startdateymd => '2015-08-09',
    #                :enddateymd => '2015-08-09',
    #                :startdateymd => Time.parse("2015-08-03 12:00:00").to_i,
    #                :enddateymd => Time.parse("2015-08-09 12:00:00").to_i,
    #                :lastupdate => Time.parse("2015-08-08 12:00:00").to_i,
                    :oauth_nonce => rand(10 ** 30).to_s(16),
                    :oauth_signature_method => 'HMAC-SHA1',
                    :oauth_timestamp => Time.now.to_i,
                    :oauth_version => '1.0',
                    :oauth_token => oauth_token
                  })
    params = params.to_a.map() do |item|
      [item.first.to_s, CGI.escape(item.last.to_s)]
    end.sort
    param_string = params.map() {|key, value| "#{key}=#{value}"}.join('&')
    base_string = ['GET', CGI.escape(url), CGI.escape(param_string)].join('&')
    secret = [WITHINGS_OAUTH_CONSUMER_SECRET, oauth_token_secret].join('&')
    digest = OpenSSL::HMAC.digest('sha1', secret, base_string)
    signature = Base64.encode64(digest).chomp.gsub( /\n/, '' )
    uri_string = url + '?' + param_string + '&oauth_signature=' + CGI.escape(signature)
    #p uri_string
    
    Net::HTTP.version_1_2
    uri = URI.parse(uri_string)
    json = Net::HTTP.get(uri)
    result = JSON.parse(json)
    pp result
    

     要するにリクエスト毎に変わるOAuth1.0の署名(oauth_signature)の生成を自動化するためのスクリプトです。gem のソースコードこのサイトを参考にしました。RailsでTwitterのAPI使う時はgemが勝手にやってくれるので今までこの作業を自前でやったことはなかったため、サーバーからのエラーが無くなるまで結構手間取りました。サーバーがステータスコード「342 : The signature (using Oauth) is invalid」を返してくるわけですが、必ずしも署名の作成の仕方が悪いわけではないようです2。サーバー側でもう少しパラメータのチェックを優先して、それに沿ったエラーを返して欲しいところですがどうなのでしょう。

    スクリプト実行結果

     とにかくこれで準備はできたので後はアイデアだけ。気が向けばこのWithings APIを使ったアプリを作ってみようと思ってます。


    1. 複数のスイス時計メーカーがスマートウォッチを発表腕時計好きもグッとくる絶品スマートウォッチ特選編グッチも!?有名ブランドが続々発売するスマートウォッチ市場が熱い!! 

    2. 例として上記スクリプトのstartdateパラメータをセットしている行で.to_iを削除すると{“status” => 342}が返ってきます。