tshohe's memo

おぼえたことをかく

iPhoneのヘルスケアのデータをKibanaで見てみる

ウェアラブルバイスを使っているとiPhoneのヘルスケアにいろいろな情報が蓄積されていくので、それらのデータをエクスポートして可視化してみます。

勿論各デバイスごとの可視化ツールやヘルスケア自身のグラフがあるので、普通に波形が見たいだけであればそれで十分かと思いますが、Aggregationやらなんやらをやりたい場合はElasticsearchに投入してKibanaで見るほうがいろいろと便利かなーと思います。

ヘルスケアデータのエクスポート

ヘルスケアアプリケーションの右上の人型のアイコンを選択し、プロフィール画面に移動します。

f:id:tshohe:20180810013836p:plain

プロフィール画面の一番下にある「ヘルスケアデータを書き出す」というところからエクスポート出来ます。

f:id:tshohe:20180810013849p:plain

LogstashからElasticsearchへ投入

xml filter を利用することで、XML形式のヘルスケアデータをElasticsearchへ投入します。

conf

input {
  file {
    path => "/tmp/healthcare.xml"
    type => "helthcare"
    start_position => "beginning"
  }
}

filter {
  if [type] == "helthcare" {
    xml {
      source => "message"
      store_xml => "false"
      remove_namespaces => "true"
      xpath => ["Record/@type", "metricsType"]
      xpath => ["Record/@sourceName", "sourceName"]
      xpath => ["Record/@creationDate", "creationDate"]
      xpath => ["Record/@value", "value"]
    }
  }
  if [creationDate] != "" {
    mutate {
      replace => {"metricsType" => "%{metricsType[0]}"}
      replace => {"sourceName" => "%{sourceName[0]}"}
      replace => {"creationDate" => "%{creationDate[0]}"}
      replace => {"value" => "%{value[0]}" }
    }
  }
}

output {
  if [metricsType] != "" {
    elasticsearch {
      hosts => localhost
      index => "healthcare-%{+YYYY.MM.dd}"
    }
  }
}

template

PUT _template/healthcare
{
  "index_patterns": "healthcare-*",
  "mappings": {
    "doc": {
      "dynamic_templates": [
        {
          "integers": {
            "match_mapping_type": "long",
            "mapping": {
              "type": "long"
            }
          }
        },
        {
          "strings": {
            "match_mapping_type": "string",
            "mapping": {
              "type": "keyword"
            }
          }
        }
      ],
      "properties": {
        "creationDate": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss Z"
        },
        "value": {
          "type": "long"
        }
      }
    }
  }
}

indexはこんな感じ

GET healthcare-*/_search?size=1

{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 10639,
    "max_score": 1,
    "hits": [
      {
        "_index": "healthcare-2018.08.10",
        "_type": "doc",
        "_id": "5hdrJGUBVvfK6smIRtRR",
        "_score": 1,
        "_source": {
          "metricsType": "HKQuantityTypeIdentifierHeartRate",
          "value": "98",
          "path": "/tmp/healthcare.xml",
          "@version": "1",
          "@timestamp": "2018-08-10T15:18:41.852Z",
          "host": "hostname",
          "type": "helthcare",
          "sourceName": "iPhone",
          "creationDate": "2017-11-27 21:56:01 +0900"
        }
      }
    ]
  }
}

どのmetricsType(/HealthData/Record/@type)がどんな意味を持っているかはAppleのDocumentに記載されています。

Health Data Types | Apple Developer Documentation

日毎の心拍数の最大値のグラフを描画するとこんな感じ(時計付けてない日も多くて結構抜けてる...)

f:id:tshohe:20180811002938p:plain

心拍数ランキングとかも描画できる

f:id:tshohe:20180811003347p:plain

他にも

  • GPS情報のTileMapへの描画
  • 睡眠時間のグラフ化
    • 一定基準下回るとアラート上げたり

等色々と遊べそうです。

より便利にするためには

今はiPhoneでエクスポートして、移動して、展開して...みたいな手順で何かと手間がかかりますが、エクスポート先としてSlackやGoogle Driveが選択できるので、例えば

といったこともできるはずです。