LoginSignup
7
2

More than 1 year has passed since last update.

termux×AWS IoT でスマホ位置情報をAWSに送信

Last updated at Posted at 2020-10-16

はじめに

妻に、「職場を出たらラインしろ」と言われているのですが、正直面倒です。
自分が職場を出たことを自動で通知できないかなと思い、とりあえず位置情報をAWSに送ってみました。

図1.png

環境

スマホ:京セラ(KTV44)
OS:Android 9

スマホ(termux)側

AndroidにGoogle Playを利用して、termuxをインストールします。
https://play.google.com/store/apps/details?id=com.termux&hl=ja

スマホだとキーボード入力しづらいため、
インストール後に下記コマンドを入力し、ssh用の環境を構築します。

$ apt upgrade #とりあえず最新にする。
$ termux-setup-storage #termuxにandroidストレージの使用を許可する。
$ pkg install openssh #ssh(サ-バ、クライアント両方)をインストール
$ sshd #sshサーバを起動
$ passwd #パスワードの設定
$ whoami #ユーザ名の確認(メモしてください。)
$ ifconfig #スマホのIPアドレスの確認(メモしてください。)

ちなみに、termuxで表示されるIPアドレスはスマホ自体のIPアドレスと一緒なので、あらかじめ分かっていればifconfigしなくても大丈夫です。

次に作業しやすいようにPCからsshでスマホに接続します。
ここで注意です.
sshのデフォルトのTCPポート番号は22ですが、termuxの場合は8022が指定されています。
そこで-pオプションでポート番号を指定します。
PC(Ubuntu)側

$ ssh -p 8022  (ユーザ名)@(スマホのIPアドレス)

最初にsshをした場合、
Are you sure you want to continue connecting (yes/no)?
と出るので、yesと回答。
その後、スマホで設定したパスワードを入力します。

初期状態ではバックグラウンド処理が禁止されているため、スマホがスリープ状態になるとsshの接続がその都度中断されててしまいます。
スマホで「RELEASE WAKELOCK」を選択することで、バックグラウンド処理が行われるようになる。

Screenshot_20201015-214307.png

sshで入れるようになったら、引き続き環境を構築していきます。

$ pkg install git #後に使用するAWS IoT Core用にgitをインストールしておく。
$ pkg install python #Pythonもインストールしておく。
$ pkg install vim-python #ファイル編集用にvimもインストールしておく。
$ pkg install termux-api #termux-apiもインストールしておく。GPS情報を取得するために必要。

インストール系が終了したら、次はAWS Iot Coreを設定します。
この↓記事を参考に「android01」なるモノを登録し、スマホからAWSへの接続テストまで行います。
https://qiita.com/zakuzakuzaki/items/e30d63598ca1d6c0f2a9

意外とそのままできたのでびっくりです。
termuxすごい。

「termux-api」の中の、termux-locationコマンドで、位置情報を取得します。
https://wiki.termux.com/wiki/Termux-location

$ termux-location -p network #スマホが観測している現在位置を出力
{
  "latitude":   35.6359322,
  "longitude": 139.8786311,
  "altitude": 43.5,
  "accuracy": 23.26799964904785,
  "vertical_accuracy": 3.299999237060547,
  "bearing": 0.0,
  "speed": 0.0,
  "elapsedMs": 97,
  "provider": "network"
}

-pは、位置情報の取得手段を選択するオプションで[gps/network/passive]の中から選択します。
デフォルトだとgpsですが、なぜか自分のスマホではできませんでしたので、networkを選択しました。
(エラーも出ず、ずっと待ち状態になる。)
ちなみにスマホをWi-Fi接続から3G接続に変えても、networkを選択しないと位置情報を取得できません。

おそらくtermuxアプリの権限の問題だと思いますが、解決できなかったので放置しました。
通常、androidはアプリの設定画面でアプリ毎にフォルダ、カメラ、GPSなどの利用権限が付与できるのですが、
termuxはそもそも権限の選択肢が出てこないので、付与のしようがありません。

位置情報が取得できることが確認できたら、処理しやすいようにしてjson形式で保存します。

$ termux-location -p network |sed -e "4,10d"|tr -d '\n'|tr -d ' '| sed -s s/,}/}/g > location.json
$ cat location.json 
{"latitude":35.6359322,"longitude":139.8786311}#いい感じに整形されたことを確認

やっていることは、
・位置情報を取得
・4~10行目(緯度経度以外)を削除
・改行を削除
・スペースを削除
・最後の” , ”(カンマ)を削除
・カレントディレクトリにlocation.jsonを保存
です。
全部の情報をそのまま送ってもいいと思うのですが、少しでも通信量を下げるために、余計なデータをカットしました。

次に、位置情報をパブリッシュするためのプログラムを作成します。
aws-iot-device-sdk-python内のサンプルファイル、「basicPubSub.py」の最後の部分を改造した、「jsonPub.py」を作成します。
位置情報が入っている、location.jsonを読み込みパブリッシュするようにします。

編集前

basicPubSub.py(112行目以降)
# Publish to the same topic in a loop forever
loopCount = 0
while True:
    if args.mode == 'both' or args.mode == 'publish':
        message = {}
        message['message'] = args.message
        message['sequence'] = loopCount
        messageJson = json.dumps(message)
        myAWSIoTMQTTClient.publish(topic, messageJson, 1)
        if args.mode == 'publish':
            print('Published topic %s: %s\n' % (topic, messageJson))
        loopCount += 1
    time.sleep(1)

編集後

jsonPub.py(112行目以降)
# Publish to the same topic in a loop forever
with open("location.json", "rb") as load_file:#位置情報ファイルの読み込み
    location = bytearray(load_file.read())#MQTT送信用にbytearray型に変換
loopCount = 0
while True:
    if args.mode == 'both' or args.mode == 'publish':
        myAWSIoTMQTTClient.publish(topic, location, 1)#位置情報をパブリッシュ
        if args.mode == 'publish':
            print('Published topic %s: %s\n' % (topic, location))#確認用
        loopCount += 1
    time.sleep(1)

これでスマホ側の構築は終わりです。

AWS側の設定

次にクラウド側の設定を行います。
といってもポリシーを変えるだけです。

AWS IoT>ポリシーから、パブリッシュ、サブスクライブしてもいいトピックを追加します。
今回は「location」という名前のトピックを追加しました。
編集が終わったら、「新しいバージョンとして保存」します。
これをしないと接続エラーが発生します。

0.PNG

テスト

AWS IoT >テストにアクセスし、トピック名(location)を入力したのち、「トピックへのサブスクライブ」をクリックします。

1.PNG

ターミナルでjsonPub.pyを実行します。
コマンドの最後に-tオプションでトピック名を指定します。

python jsonPub.py  -e (自分のARNに合わせてください)-ats.iot.ap-northeast-1.amazonaws.com -r root-CA.crt -c android01.cert.pem -k android01.private.key -t location

ターミナルに下記メッセージが出力されることを確認します。
スマホがAWSにパブリッシュした位置情報をAWSからサブスクライブできました。


Received a new message: 
b'{"latitude":35.6359322,"longitude":139.8786311}'
from topic: 
location
--------------

さらにAWS側で、locationトピックをサブスクライブしていることを確認します。
2.PNG

おつかれさまでした。

おわりに

スマホの位置情報をAWSに送信する環境を構築しました。
次は、lambda等を利用して退社自動通知や、帰りの電車の発車時刻を調べてくれたらいいですね。
ちなみに、本ページで表示している位置情報は私の家ではありませんので、ご安心ください。

今回作成したファイルは、githubにあげました。
https://github.com/zakuzakuzaki/zaki-aws/tree/main/iot

参考URL

ご協力ありがとうございました。
  
Android 端末上で開発環境を整えてみた
https://qiita.com/leosuke/items/b83425d5a6730aa4cf94

Termux で持ち運べるモバイルリポジトリを作る
https://wlog.flatlib.jp/item/1859

PythonでJSON 読み込み
https://qiita.com/kikuchiTakuya/items/53990fca06fb9ba1d8a7

追 記

AWSとは無関係ですが、IFTTT(イフト)の位置情報を用いたトリガーを使って、ほんの数分で実現したいことができました。
image.png

7
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
2