iphoneを使って自分のGPS記録を取得する（アプリ未使用）

普段持ち歩くiphoneを利用して自分の行動をGPSとして記録します。専用アプリ等を使わず、icloudの「iphoneを探す」を利用して位置を取得していきます。記録にはraspberrypiを使用します。（pythonが動けばなんでもOKだと思います。）

<B>2016/12/21追記
icloudの2段階認証を導入している場合はあらかじめraspberrypiから2段階認証を実施し、ログインできるようにしておきます。（下記に追記済み）</B>

<h1>使用環境</h1>
・Raspberry Pi 2 Model B（OS Raspbian）
・iphone（iphoneを探すをオンにしたもの）

<h1>環境準備</h1>
・raspberry piにpython環境を準備する。（デフォルトで入ってると思いますので割愛）

・pythonを利用してicloudサービスに接続するライブラリを導入する。
　以下のサイトからライブラリをダウンロードして、raspberrypiの適当な作業フォルダに保存します。

　ダウンロードサイト(github picklepete/pyicloud)
　https://github.com/picklepete/pyicloud

　ダウンロードしたファイル内の「setup.py」を実行してライブラリをインストールします。
  (以下の例はworkフォルダ内に保存しています。)
  `pi@rasberry ~/work/$ python setup.py build`
  `pi@rasberry ~/work/$ python setup.py install`
　
<B>2016/12/21追記
2016年10月以前に導入した方は、最新版をインストールしてください。</B>

　インストール完了後はpythonにてicloudの「iphoneを探す」から緯度経度情報を取得できます。ダウンロードしたファイル内にあるreadmeに[使用例](https://github.com/picklepete/pyicloud/blob/master/README.rst)が載っていますが、以下のようにプログラムを組めばgps取得できます。

<h2>①取得したい携帯電話のデバイスナンバーを取得する</h2>
　icloudに登録している台数に応じてナンバーが異なります。以下のプログラム
で該当するデバイスナンバーを確認します。

```lang:check_gps_device.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from pyicloud import PyiCloudService

#以下は接続するicloudのアカウントとパスワードを記載します。
api = PyiCloudService('XXXXXX@YYYYYYYYYY', 'password')

def get_oauth():
    auth = api.devices
    return auth

if __name__ == '__main__':
    auth=get_oauth()
    print('\n')
    print(auth)
```
実行結果は人によって異なりますが、以下通りになります。


```check_gps_device.py実行結果
{u'Q/ashasdgyuhjbdwsujbajk3joihjskbajasdakjdaiskh': <AppleDevice(iPhone 6s: xxxxxiphone6s)>, u'tdakhwdjhskshofhedkdhdjdkejidknjsncjkdsncsds': <AppleDevice(iPhone 4s: iphone4s)>, u'yhjndlsdlnceidhjskdbcnjwdsnxjksanxksajjsnxjks/3ewsdujshnsdjdskdwsd': <AppleDevice(iPhone 5s: iohone5s)>, u'uehjkadshuwjkjaha74jsjauhdkahkj': <AppleDevice(iPad: iPad)>}
```
上記の例では、icloudの「iphone6s」と「iphone5s」と「iphone4s」と「ipad」が登録されています。デバイスナンバーは記載順番で0,1,2,3となります。



<B>2016/12/21追記
2段階認証の方法を追記しました</B>
<h2>②2段階認証取得プログラム</h2>
icloudで2段階認証を有効にしてる方は、本手順を実施raspberrypiからicloudにログインできるようにします。

以下の通り2段階認証を実施します。

```lang:get_2Auth.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from pyicloud import PyiCloudService

#以下は接続するicloudのアカウントとパスワードを記載します。
api = PyiCloudService('XXXXXX@YYYYYYYYYY', 'password')

#ここから2段認証を実施する。
if api.requires_2fa:
    import click
    print "Two-factor authentication required. Your trusted devices are:"

    devices = api.trusted_devices
    for i, device in enumerate(devices):
        print "  %s: %s" % (i, device.get('deviceName',
            "SMS to %s" % device.get('phoneNumber')))

    device = click.prompt('Which device would you like to use?', default=0)
    device = devices[device]
    if not api.send_verification_code(device):
        print "Failed to send verification code"
        sys.exit(1)

    code = click.prompt('Please enter validation code')
    if not api.validate_verification_code(device, code):
        print "Failed to verify verification code"
        sys.exit(1)

def get_oauth():
    # デバイスナンバーは、icloudに登録しているデバイスに応じて数が異なる。
    auth = api.devices[0].location()
    return auth

if __name__ == '__main__':
    auth = str(get_oauth())
    s=auth.find('longitude')
    e=auth.find(u'positionType')
    s1=auth.find(u'latitude')
    e1=auth.find(u'isOld')
    lng1 =float(auth[s+12:e-4])
    lat1 =float(auth[s1+11:e1-4])
    print('%3.14f,%3.14f'%(lng1,lat1))

```
上記を実行すると2段階認証後、GPS情報を取得します。デバイス番号は①で調べた番号、2段階認証はAppleから英語で電話がかかってきますので、その番号を入力します。

```lang:get_2Auth.pyの実行結果
pi@rasberrypi ~/ $ python get_2Auth.py
Two-factor authentication required. Your trusted devices are:
  0: SMS to ********31
Which device would you like to use? [0]: 0
Please enter validation code: XXXXXX
139.61947695737689,35.62127735869860
```
上記のようにGPS情報を取得できれば成功です。
以降は2段階認証せずに取得できます。


<h2>③gps取得プログラム</h2>
確認後、gps情報を以下の通り取得します。(今回はiphone6sの情報を取得します)

```lang:get_gps.py
#!/usr/bin/env python
#-*- coding:utf-8 -*-
from pyicloud import PyiCloudService

#以下は接続するicloudのアカウントとパスワードを記載します。
api = PyiCloudService('XXXXXX@YYYYYYYYYY', 'password')

def get_oauth():
    # デバイスナンバーは、icloudに登録しているデバイスに応じて数が異なる。
    auth = api.devices[0].location()
    return auth

if __name__ == '__main__':
    auth = str(get_oauth())
    s=auth.find('longitude')
    e=auth.find(u'positionType')
    s1=auth.find(u'latitude')
    e1=auth.find(u'isOld')
    lng1 =float(auth[s+12:e-4])
    lat1 =float(auth[s1+11:e1-4])
    print('%3.14f,%3.14f'%(lng1,lat1))

```

実行結果は以下の通りです。


```lang:get_gps.pyの実行結果
pi@rasberrypi ~/ $ python get_gps.py
/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
  InsecurePlatformWarning
/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
/usr/local/lib/python2.7/dist-packages/requests-2.7.0-py2.7.egg/requests/packages/urllib3/connectionpool.py:768: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.org/en/latest/security.html
  InsecureRequestWarning)
139.86947695737689,35.67127775869860
```
色々怒られますが、無視して最後の行に経度と緯度が出てきます。

後は、こいつを実行してあげるシェルを書き、csvに時間情報を付加して書き出してあげれば完成です。シェルをcronで定期的に起動してあげれば任意の時間間隔でgps情報を取得できます

```lang:gps.sh
#!/bin/sh
ther=$(python /home/pi/get_gps.py)
day=$(date +%Y,%m,%d,%H,%M,%S)
echo "$day,$ther" >> /home/pi/gps.csv
```

他にもこのライブラリを使用すると、なくした時の音を出したり、カレンダーを編集できたりするみたいですね。

気軽にgps情報を取得できる便利な世の中です。

集積した情報は以下のサイトなどを使用して可視化すると面白いです。
http://www.tree-maps.com/prot/
http://memopad.bitter.jp/web/GoogleMap/V3/myMap/tools/gpsDataDisplay.html