Help us understand the problem. What is going on with this article?

Node-RedとMQTTでスマホの位置情報をリアルタイムでモニタする

More than 5 years have passed since last update.

はじめに

スマホの位置情報を簡単に利用する方法がないか調べていたところ、OwnTracksというスマホアプリが便利そうだったので試してみた。

OwnTracksはMQTTでスマホの位置情報をMQTT Brokerに定期的にPublishしてくれるアプリであり、アプリをインストールしている友達同士で位置情報を共有したり、特定の領域内にスマホが入ったことを検知するGeo-Fenceといった機能を使うことが出来る。

このOwntracksを使って、「自分のスマホの位置情報をリアルタイムにずーっとトラッキングし続けるWebページ」をBluemixのNode-Redで作ってみた。

どんな構成か

OwntracksからMQTTでスマホの位置情報を、クラウドサービスを利用して作成したMQTT Brokerに定期的にPublishし、その位置情報をNode-Red上に作成したSubscriberが読み出して、Google Map上に表示するという簡単なもの。

役割 ツール コメント
** Publisher** OwnTracks スマホの位置情報を、設定されたMQTT BrokerにPublishする
Broker Cloud MQTT MQTT Brokerを一瞬でクラウド上に作成できるサービス。
Subscriber Bluemix / Node-Red Node-Redで提供されているMQTTのデータをSubscibeするNodeを使用

MQTT Brokerのセットアップ ( MQTT Cloud )

MQTTでの通信を行うためには、MQTT Brokerが必要であり、Mosquitto, Rabbite MQといったサーバー製品をLinuxマシンやRaspberry Piといったボードコンピュータにインストールして構成するのが一般的なようだ。

ただ、調べてみると、下記のようなMQTT Brokerをクラウド上で一瞬で構築できるサービスがあるようで、今回はMQTT Cloudというサービスを使ってみた。
* Cloud MQTT
* Sango ( 株式会社時雨堂という日本の会社が提供するMQTT as a Service )

1. MQTT Cloudのアカウント取得

Topページから、上部ナビゲーションバーの「Plan」を選択し、次の画面でFree Accountを選択し、Sing up。
2015-08-09_23h33_20.png

2. MQTT Broker Instanceの作成

Sing up後、「Control Panel」より、「+ Create」ボタンを押して、MQTT Broker Instanceを作成。インスタンス名の入力だけで、他は特に変更せずにOK。
インスタンスの詳細を表示すると下記のような情報が表示される。下記の情報をPublisher/Subscriber双方で使用するので、メモをしておく。
* server
* User
* Password
* Port

2015-08-10_09h21_58.png

MQTT Publisherの設定( Owntracks )

アプリケーションをダウンロードして、Publisher側の設定をする。これから設定する内容の概要を説明すると、「MQTT Brokerへのログイン情報を設定し、位置情報をPublishするTopicを設定する」といった作業をすることになる。

アプリを起動し、「Settings」にて、Modeを「Private」にし、下記の4項目の設定を行う。
*** Host - 作成したMQTT Broker インスタンスの「Server」のアドレス**
* Port - 同じくインスタンスの「Port」 (今回はSSLを使用しないので、SSL Portではなく、ただのPort)
* UserID - 同じくインスタンスの「User」
* Password - 同じくインスタンスの「Password」
* Device ID - 任意のデバイス名を指定

2015-08-10_10h02_39.png

OwnTracksでは、UserIDとDeviceIDを元に、位置情報をPublishするTopic名が決められる。Topicは特定のデータの投稿先で、PublisherがTopicにデータを送信し、SubscriberはTopicを購読するようにBrokerにSubscribeしておき、BrokerはSubscribeしているSubscriberにTopicに届いた情報を配信する。Topic情報は、Subscriberを設定する際に必要になるので、メモしておく。

owntracks/[UserID]/[DeviceID]

設定後、アプリ画面上部の「Check」をタップし、「Connnected」となれば、MQTT Brokerへの接続が成功である。

MQTT Broker上での接続確認

OwnTracksから位置情報が正しくMQTT BrokerにPublishされているかどうかを確認する。
MQTT Cloudでは、Brokerに届いたメッセージをWebSocketを用いてリアルタイムで確認可能なツールがあるので、これを使って動作確認をする。MQTT Cloudのインスタンスの詳細情報画面(ServerアドレスやUser名、Passwordが確認出来る画面)の上部に、「WebSocket UI」というボタンあるので、コレをクリックすると確認可能だ。

正しくPublishされていると下記のように、OwnTracksがPublishした位置情報が表示される。

2015-08-10_10h21_07.png

注意点

  • スマートフォンにて、OwnTracksがGPS等の位置情報にアクセス可能なように設定すること。
  • テストが終わったら、位置情報の配信は止めること(止めた方が良いです。。)

Subscriberの設定( Node-Red )

MQTT BrokerのTopic(owntracks/[UserID]/[DeviceID])を購読するようにSubscribeする。(Node-Redの使用方法は他のQiitaの記事等を参照してください。)

Subscriberとして使用するのは、下記の「MQTT In」Node。
2015-08-10_10h49_48.png

下記のように設定する。設定内容としては、OwnTracksとほぼ同じ内容である。
2015-08-10_10h48_53.png

Topicには、owntracks/[UserID]/[DeviceID]を指定する。
2015-08-10_10h53_21.png

うまく接続されれば、下記のようにNodeの下に「Connected」と表示され、Debug Nodeにつなぎ、OwnTracks側から「Publish Now」を押して、位置情報をPublishすると、Topicが受信でき、結果がNode-RedのDebug Windowに表示される。

2015-08-10_10h54_26.png
2015-08-10_10h57_13.png

位置情報のマッピング

Node-Redでの位置情報のマッピングはこちらのQiitaの投稿が参考になる。ほとんど同じ実装で、WebsocketでMQTTから得られた位置情報をリアルタイムでGoogle Map上に表示させている。

下記の設定だと、Bluemixで割り当てられたApplicationのBase URLに、/mapを加えたURLにブラウザからアクセスすると、スマホの位置がGoogle Map上に表示される。

2015-08-10_11h13_53.png

上記のFlowは下記の情報をNode-RedでImportしてください。

[{"id":"2cd7f590.29844a","type":"websocket-listener","path":"/ws/location","wholemsg":"false"},{"id":"bdaa2a8.f98e958","type":"mqtt-broker","broker":"m11.cloudmqtt.com","port":" \t10212","clientid":""},{"id":"3261c734.ff3838","type":"mqtt in","name":"","topic":"owntracks/ealsglxm/iphone","broker":"bdaa2a8.f98e958","x":209.33331298828125,"y":70.33334350585938,"z":"35bec190.918f46","wires":[["b58b0a8e.4d8d58","c7b9da8b.7929f8"]]},{"id":"b58b0a8e.4d8d58","type":"debug","name":"","active":true,"console":"false","complete":"false","x":428.33331298828125,"y":71.33332824707031,"z":"35bec190.918f46","wires":[]},{"id":"b4b761b2.d40b8","type":"websocket out","name":"","server":"2cd7f590.29844a","x":813.3333129882812,"y":226.33334350585938,"z":"35bec190.918f46","wires":[]},{"id":"92142786.1ec2","type":"websocket in","name":"","server":"2cd7f590.29844a","client":"","x":391.33331298828125,"y":258.3333435058594,"z":"35bec190.918f46","wires":[["44852596.df2134"]]},{"id":"a35c3ced.3c69d","type":"http in","name":"","url":"/map","method":"get","swaggerDoc":"","x":280.33331298828125,"y":328.3333435058594,"z":"35bec190.918f46","wires":[["236a7bcb.035bb4"]]},{"id":"dbbda48e.7bacc","type":"http response","name":"","x":728.3333129882812,"y":328.3333435058594,"z":"35bec190.918f46","wires":[]},{"id":"236a7bcb.035bb4","type":"template","name":"","field":"","template":"<!DOCTYPE html>\n\n

\n Owntracks & The ThingBox Live Map\n \n \n \n \n \n\n\n \n
\n \n\n","x":500.33331298828125,"y":328.3333435058594,"z":"35bec190.918f46","wires":[["dbbda48e.7bacc"]]},{"id":"44852596.df2134","type":"function","name":"function 2","func":"// The received message is stored in 'msg'\n// It will have at least a 'payload' property:\n// console.log(msg.payload);\n// The 'context' object is available to store state\n// between invocations of the function\n// context = {};\n\nmsg.payload = context.global.location;\n\nreturn msg;","outputs":1,"noerr":0,"x":621.3333129882812,"y":258.3333435058594,"z":"35bec190.918f46","wires":[["b4b761b2.d40b8"]]},{"id":"a02ee9d2.dd6b88","type":"function","name":"function 1","func":"// The received message is stored in 'msg'\n// It will have at least a 'payload' property:\n// console.log(msg.payload);\n// The 'context' object is available to store state\n// between invocations of the function\n// context = {};\ncontext.global.location = msg.payload;\n\nreturn msg;","outputs":1,"noerr":0,"x":618.3333282470703,"y":197.33334350585938,"z":"35bec190.918f46","wires":[["b4b761b2.d40b8"]]},{"id":"65ff2d00.eea4dc","type":"function","name":"Adaptation","func":"var latitude = msg.payload.lat;\nvar longitude = msg.payload.lon;\nmsg.payload = '[{\"lat\":\"' + latitude + '\",\"lng\":\"' + longitude + '\"}]'; \nreturn msg;","outputs":1,"noerr":0,"x":454.33331298828125,"y":198.33334350585938,"z":"35bec190.918f46","wires":[["a02ee9d2.dd6b88","8e4087bf.d5131"]]},{"id":"8e4087bf.d5131","type":"debug","name":"","active":true,"console":"false","complete":"false","x":629.3333129882812,"y":124.33331298828125,"z":"35bec190.918f46","wires":[]},{"id":"c7b9da8b.7929f8","type":"json","name":"","x":413.33331298828125,"y":127.33334350585938,"z":"35bec190.918f46","wires":[["65ff2d00.eea4dc"]]}]
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした