ライブ・スペース・トラッキングによるインテリジェント・パーキング・システム
Published: 2024-01-11 12:08:52

あらゆる「モノ」がインターネットによってシームレスに相互接続される時代は、かつてなかった。[モノのインターネット（IoT](https://www.pubnub.com/solutions/iot-device-control/)）という考え方は、**イベント・ドリブン・パブ／サブ・アーキテクチャを**使用して多くの問題に対する革新的なソリューションを提示することで、我々の世界を絶えず変革してきた。例えば、混雑したスペースで駐車場を探すという疲れる問題を解決するために、駐車場は駐車場の個々のセンサーから公開されるステータス更新を購読することで、どのスポットが空いているかを示すライブ電子ダッシュボードを設置している。このようなIoTアプリの構築は、多くのハードルのために困難である可能性がある。

これらのハードルの1つは、モバイルアプリとセンサーデバイスの間でリアルタイムで送信されるメッセージを処理できるサーバーをホストすることである。もうひとつは、スマート駐車場内の埋め込みセンサー・デバイスひとつひとつをサポートできる無線LANネットワークのホスティングだ。

しかし、**PubNubと** **Soracomを**並行して使用することで、開発者はこれらの課題を迅速に回避することができる。PubNubのリアルタイム・プラットフォームを使えば、開発者はサーバーのホスティングなどの面倒な作業を心配することなく、[車両監視](https://www.pubnub.com/solutions/transport-delivery/)用の[複雑なIoTソリューションを](https://www.pubnub.com/solutions/iot-device-control/)簡単に[構築](https://www.pubnub.com/solutions/iot-device-control/)できる。さらに、[Soracom Airと](https://www.soracom.io/products/air/) [Soracom Beamを](https://www.soracom.io/products/beam/)使えば、開発者は制限の多いWFIネットワークではなく、LTEを利用したIoTソリューションを簡単に構築できる。

チュートリアル概要
---------

このチュートリアルでは、Raspberry Piと超音波センサーを使用して、駐車場が埋まっているか空いているかを検出するスマートパーキングシミュレーションを構築します。Soracom Airを使ってセンサーからセルラーデータ経由でPubNubにメッセージを送信します。そして、PubNubのPublish-Subscribe APIを使って、ライブの駐車場データをアプリのすべてのモバイル・ユーザーに即座に提供します。これを以下の図に示します。

* * *

**完全なソースコードについては、[ここをクリックして](https://github.com/PubNubDevelopers/Smart-Parking)**ください。

* * *

[![Smart Parking Lot](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1ja5/9d106e47efa5221bc12537d32cfa2d3a/screenshot.png "Smart Parking Lot")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1ja5/9d106e47efa5221bc12537d32cfa2d3a/screenshot.png)

このデモを構築するには、以下のものが必要です：

1.  ラズベリーパイ（バージョン問わず）
2.  ブレッドボード
3.  HC-SR04超音波センサー
4.  メス-メス1本 + オス-メス6本のジャンパーワイヤー
5.  1**kΩ**抵抗1本と**2kΩ**抵抗1本
6.  MicroSDカード + MicroSDからSDへのアダプタ
7.  Huawei USBスティックモデム
8.  Soracom Air Simカード

Raspberry Piのセットアップ
-------------------

### **1.Raspbian OSのインストール**

まだの方は、Raspberry PiにRaspbian OSをインストールしてください。そのために、まずローカルにインストールします。これはディスクイメージ形式なので、使用する前にディスクをフラッシュする必要があります。[Etcherを使って](https://www.balena.io/etcher/)ディスクをmicroSDカードアダプターにフラッシュすることができます。

[![Smart Parking Lot](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1ja6/56bde9961fc7faffc78d276cc5dd8916/Screen-Shot-2018-07-31-at-12.47.07-PM.png "Smart Parking Lot")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1ja6/56bde9961fc7faffc78d276cc5dd8916/Screen-Shot-2018-07-31-at-12.47.07-PM.png)

RaspbianのOSファイルをmicroSDカードアダプターに入れたら、microSDカードをアダプターから取り外し、Raspberry Piの一番下のスロットに挿入します。OSがインストールされたら、キーボード、マウス、モニター、電源を接続してRaspberry Piを起動します。

### 2.センサーの設定

[![Smart Parking Lot](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1ja7/9791eceb9d4aa6d43903901e40097b21/Screen-Shot-2018-07-31-at-1.45.55-PM.png "Smart Parking Lot")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1ja7/9791eceb9d4aa6d43903901e40097b21/Screen-Shot-2018-07-31-at-1.45.55-PM.png)

1.  **超音波センサーHC-SR04の** **VCC、Echo、GNDスロットに** 、**オスとメスのジャンパー線**3本を差し込む **。** センサーの**Trig**スロットに、**メスとメスのジャンパー線**1本を差し込む。
2.  **VCC** **ワイヤーを**ブレッドボードの**プラスレールに**、**GND** **ワイヤーを** **マイナスレールに**差し込む。
3.  Raspberry Piの**GPIO 5Vを**ブレッドボードのプラス**レールに**、**GPIO GNDを**マイナス**レールに**接続する。
4.  **Trig**ワイヤーを**GPIO 23に**接続する。
5.  **Echo**ワイヤーをブレッドボードの**ブランクレ**ールに差し込む。
6.  **1kΩの抵抗を**使用して、別の空白のレールに接続する。(抵抗が必要な理由は、センサーの構成によってRaspberry Piが損傷しないように電圧出力を下げるためです）。
7.  次に、**2kΩ抵抗** を使って空白のレールをブレッドボードのマイナスレールにつなげます。2kΩの抵抗がない場合は、次の図のように1kΩの抵抗を2本連ねてください。[![IMG_20180731_151118-1](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1ja9/1c9c8a5ed42e0d91b802e6dd117bcd1a/IMG_20180731_151118-1.jpg "IMG_20180731_151118-1")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1ja8/3f8e169838914d011b94fa213f65b1b7/IMG_20180731_151118-1.jpg)
8.  空いたスペースに、**オスとメスのジャンパーワイヤーを使って** **GPIO 24に**リンクします。

これで超音波センサーの設定は完了です。もしセンサーの設定に行き詰まったら、こちらの[チュートリアルを](https://thepihut.com/blogs/raspberry-pi-tutorials/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi)参照してください。回路を作っている間、[ブレッドボードの](https://en.wikipedia.org/wiki/Breadboard)ブランク・レールでは電流が水平に流れ、ブレッドボードのプラスとマイナスのレールでは電流が垂直に流れることを覚えておいてください。次に、PubNubとSoracomをIoTアプリにセットアップします。

PubNubのセットアップ
-------------

まず、[PubNub Admin Consoleで](https://dashboard.pubnub.com/login)アプリを作成する**（無料**）。コンソールでアプリを作成すると、次のステップでPubNubとSoracomを接続するために使用するPublishキーとSubscribeキーが表示されます。

Soracomのセットアップ
--------------

### **SIMの登録**

[Soracom Admin Consoleに](https://console.soracom.io/)移動します。ここで「SIMを**登録**」をクリックし、**Soracom Air Simカードの**裏面に記載されている**ICCIDと** **PUKを**入力します。

[![imageedit_2_3979299183](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jab/26b73ca8e719f9eaf8cc42ea2c631087/imageedit_2_3979299183.png "imageedit_2_3979299183")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jaa/2dcb1f4a63420c662d7dbcf859027a23/imageedit_2_3979299183.png)[![Smart Parking Lot](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jac/d927cf8efc47161a592fd4ea756a69d5/Screen-Shot-2018-07-31-at-3.47.58-PM.png "Smart Parking Lot")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jac/d927cf8efc47161a592fd4ea756a69d5/Screen-Shot-2018-07-31-at-3.47.58-PM.png)

### USBモデムの設定

SIMカードを登録した後、SIMチップを取り出します（上の画像では紫色の丸で囲んでいます）。そして**Huawei USB Stick Modemに**挿入します。SIMカードが上向きになっていることを確認してください。

[![Smart Parking Lot](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jad/dddd1f8435888122020be80479bfe8de/Screen-Shot-2018-08-01-at-11.21.56-AM.png "Smart Parking Lot")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jad/dddd1f8435888122020be80479bfe8de/Screen-Shot-2018-08-01-at-11.21.56-AM.png)

Raspberry Piをセルラーデータで動かすには、[Huawei USB Stick Modemを](https://consumer.huawei.com/en/routers/e3372/specs/)Raspberry PiのUSBポートに差し込むだけです。 **青く点灯して**いれば（点滅していなければ）、モデムが3Gデータを正常に受信していることを示している。点滅している場合は、まだ接続しようとしていることを意味する。

[![IMG_20180801_141334](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jaf/445f100919feb6626cc4f1167b36f290/IMG_20180801_141334.jpg "IMG_20180801_141334")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jae/a9574a8b0e9a08f80e430d03605c3bbd/IMG_20180801_141334.jpg)

青いライトが点灯したら、USBスティックモデムをRaspberry PiのNetwork Managerに追加します。これを行うには、まずRaspberry PiにNetwork Managerをインストールします。Raspberry Piのターミナルで次のように入力します。

```js
sudo apt-get update && sudo apt-get install network-manager
```

次に、USBスティックモデムをSoracomアカウントに接続するために、Raspberry Piのターミナルから以下のコマンドを入力します。**<ENTER\_USERNAME>と** **<ENTER\_PASSWORD>を**それぞれのアカウント認証情報に置き換えてください。

```js
sudo nmcli con add type gsm ifname "*" con-name soracom apn soracom.io user <ENTER_USERNAME> password <ENTER_PASSWORD>
```

この設定を有効にするには、Raspberry Piを再起動する必要があります。

```js
sudo reboot
```

USBモデムがRaspberry Piのネットワーク・マネージャーに認識されていることを確認するために、次のように入力します：

```js
ifconfig
```

と入力します。

```js
ppp0
```

(USBモデム）が表示されるはずです。次に以下の3つのターミナルコマンドを入力し、Soracomのppp route metricスクリプトをダウンロードし、USBモデムを接続または再起動するたびにスクリプトが実行されるようにします。

```js
sudo curl -o /etc/NetworkManager/dispatcher.d/90.set_ppp_route_metric https://soracom-files.s3.amazonaws.com/handson/90.set_ppp_route_metric
```

```js
sudo chmod +x /etc/NetworkManager/dispatcher.d/90.set_ppp_route_metric
```

```js
sudo /etc/NetworkManager/dispatcher.d/90.set_ppp_route_metric ppp0 up
```

これでUSBスティックモデムは正しく設定されたはずです。まだUSBスティックモデムの設定に行き詰っている場合は、[Soracomのドキュメントを](https://github.com/soracom/handson/wiki/1.3.-USB-Dongle-configuration-tutorial-(SIM-pre-registered))よく読んでください。

### MQTTセットアップ

[**MQTT**](https://www.pubnub.com/guides/mqtt/) (Mosquitto)はRaspberry Pi IoTアプリからPubNubチャンネルにメッセージを発行するために使用するプロトコルの名前です。管理コンソールでサイドナビゲーションバーのGroupsというリンクを開き、**新しいグループを**追加します。この新しいグループを**Beam-Soracomと**呼びます。この新しいグループの基本設定で、**Soracom Beam** をクリックする。ここで、**MQTTエントリー**ポイントを作成します。[MQTT](https://www.pubnub.com/blog/what-is-mqtt-use-cases/)Entry Point を作成する際、以下のように入力されていることを確認してください。Destination Type に**PubNub** を指定する必要があります。**Credentials Setと**表示されているところに、[PubNubの](https://admin.pubnub.com/#/register)認証情報**（PublishとSubscribe Key**）を追加して、SoracomデバイスがPubNubチャネルにメッセージを発行できるようにします。

[![IMG_20180801_141334](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jag/91b258ac62700455e397540e39711e13/Screen-Shot-2018-07-31-at-3.55.03-PM.png "IMG_20180801_141334")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jag/91b258ac62700455e397540e39711e13/Screen-Shot-2018-07-31-at-3.55.03-PM.png)

次に、管理コンソールで登録済みSIMカードを選択し、そのグループを先ほど作成した**Beam-Soracomに**設定します。 登録済みSIMカードの**activateを**クリックし、アクティブになってデータを取得していることを確認します。

次に、Raspberry Piに**mosquitto-clients**パッケージをインストールして、MQTTのpublishメソッドを使えるようにします。Raspberry Piのターミナルで以下のコマンドを実行する。

```js
sudo apt-get update && sudo apt-get install mosquitto-clients
```

mosquitto-clientsがインストールされたので、**mosquitto\_pub**コマンドをテストします。mosquitto\_pubコマンドの書式は以下のようになります。**tの**後にチャンネル名**parking\_spotを**挿入します。そして**\-m**の後にテストメッセージ "test" を挿入します。PubNubアドミンコンソールでデバッグビューを表示します。Raspberry Piのターミナルで以下のコマンドを実行すると、メッセージがPubNubチャンネルに正常にパブリッシュされたことが確認できるはずです。

```js
mosquitto_pub -h beam.soracom.io -p 1883 -t parking_spot  -m "test"
```

[![Smart Parking Lot](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jah/c9c174db5a0b05b0f6e55c495a2a30fd/Screen-Shot-2018-08-02-at-12.42.00-PM.png "Smart Parking Lot")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jah/c9c174db5a0b05b0f6e55c495a2a30fd/Screen-Shot-2018-08-02-at-12.42.00-PM.png)

これでSoracom Air DeviceはRaspberry PiからPubNubチャンネルにメッセージを正常にパブリッシュできるようになりました。これで、超音波センサーからパブリッシュし、Androidモバイルアプリからサブスクライブするコードを書き始める準備ができました。

発行 - 超音波センサーPythonスクリプト
-----------------------

pythonコードを**sensor\_publish.pyという**スクリプトに書きます（このスクリプトはRaspberry Piの中にある必要があります！）。スクリプトの先頭で必要なモジュールをインポートすることから始めます。**RPI.GPIO** モジュールはセンサーからデータを取得します。**time** モジュールは、センサーから定期的に読み取り値を取得します。**Signalと** **sysは**、ユーザがコマンド^Cを使用したときにスクリプトを終了し、センサ・データの読み取りを停止するメソッドを記述します。**Subprocessと** **jsonは**、booleanを適切なJSON Stringフォーマットにパースし、[PubNubチャネルに](https://www.pubnub.com/docs/general/channels/overview)送信します。

```js
import RPi.GPIO as GPIO
import time
import signal
import sys
import subprocess
import json
```

### センサーのセットアップ

モジュールをインポートした後、GPIOオブジェクトがRaspberry Piボードのピン番号を使用していることを確認する必要があります。次の行でこれを行います。

```js
GPIO.setmode(GPIO.BCM)
```

次に、入力ピンと出力ピンに値を割り当てる必要があります。入力ピンは**ECHO**、出力ピンは**TRIGと**呼びます。ECHOは18番ピン**（GPIO 24**）に接続され、TRIGは16番ピン**（GPIO 23**）に接続されています。また

```js
occupied
```

変数を初期化する必要があります。Falseに初期化します。

```js
TRIG = 23
ECHO = 24
occupied = False
```

次に、センサーをセットアップする関数を定義します。この関数を

```js
setup_sensor()
```

.ここで、どのピンが入力で、どのピンが出力かを定義しなければなりません。この関数は後でメイン関数の中で呼び出します。

```js
def setup_sensor():
  GPIO.setup(TRIG, GPIO.OUT)
  GPIO.setup(ECHO, GPIO.IN)
```

### センサー距離の読み取り

関数

```js
get_distance()
```

関数を使用して、物体がセンサーからどのくらい離れているかのデータを取得します。この関数は、パルス信号が物体を通過して戻ってくるまでの時間を計算します。その時間を使って、センサーから物体までの距離を計算します。

```js
def get_distance():
  # set Trigger to HIGH
  GPIO.output(TRIG, True)
  # set Trigger after 0.01ms to LOW
  time.sleep(0.00001)
  GPIO.output(TRIG, False)
  startTime = time.time()
  stopTime = time.time()
  # save start time
  while 0 == GPIO.input(ECHO):
    startTime = time.time()
  # save time of arrival
  while 1 == GPIO.input(ECHO):
    stopTime = time.time()
  # time difference between start and arrival
  TimeElapsed = stopTime - startTime
  # multiply with the sonic speed (34300 cm/s)
  # and divide by 2, because there and back
  distance = (TimeElapsed * 34300) / 2
  return distance
```

### 駐車スペースの空き状況の公開

pythonスクリプトのメイン関数で駐車場の空き状況を公開します。これはスクリプトが開始されると実行される関数になります。main関数は以下の処理を順番に行う必要があります。

1.  センサーのセットアップ
2.  駐車場の空き状況の初期チェックを行う。
3.  ステータスが変更されたかどうかをチェックする（5秒ごと）：ステータスが変更された場合、新しいステータスのメッセージを発行する。このステータスを新しい最終更新ステータスとして保存する。

センサーをセットアップするために、先ほど定義した関数を呼び出す、

```js
setup_sensor()
```

.次に、駐車スペースが空いているかどうか、初期チェックを行います。メソッド

```js
initial_check()
```

メソッドを定義します。

そして、5秒ごとにループを実行し、車の新しい距離をチェックします。関数

```js
get_distance()
```

が7cm（私のモデルでは駐車スペースの長さ）より大きければ、その駐車スペースは空いていると推測できます。この場合、車間距離は単なるノイズである。もし7cmより小さければ、その駐車スペースには車が停まっていることになる。

経費を最小限に抑え、効率を最大化するため、センサーが前回の読み取りからステータスが変化したことを示す場合にのみ、駐車スペースのステータスを更新する。これを以下に示す：

```js
if __name__ == '__main__':
  setup_sensor()
  initial_check()
  while True:
    if (occupied and (get_distance() >= 7)) or (not occupied and (get_distance() < 7)):
         // TODO toggle the availability of the parking space and publish new status
    time.sleep(5)
```

これは以下のとおりです。

```js
initial_check()
```

関数は変数

```js
occupied
```

に駐車スペースの現在のステータスを代入します。先ほどインポートした

```js
subprocess
```

モジュールを使って公開しなければなりません。このモジュールを使うと、pythonスクリプトからターミナルコマンドを実行することができます。メソッド

```js
Popen()
```

メソッドを使って、ターミナルで入力するようにコマンドから文字列の配列を渡します。**m の**後に、JSON 文字列としてエンコードされたメッセージを渡します。

```js
occupied
```

.これは、ヘルパー・メソッド

```js
convertToJsonString()
```

を呼び出すことで、これを行うことができる。

```js
def initial_check():
  occupied = True if get_distance() < 7 else False
  subprocess.Popen(["mosquitto_pub", "-h", "beam.soracom.io", "-p", "1883", "-t", "parking_spot", "-m", convertToJsonString(occupied)], stdout=subprocess.PIPE)
  print(occupied)
```

```js
def convertToJsonString(occupied):
  dictionary_object = {
    "occupied": occupied
  }
  return json.dumps(dictionary_object)
```

最後に、メイン関数の中で5秒ごとに実行されるループの中で、次のコードを書きます。これは、占有されているブール値をトグルし、最後に更新されたステータスと異なる場合は**、** それを**parking\_spot**チャンネルに公開します。

```js
occupied = not occupied
subprocess.Popen(["mosquitto_pub", "-h", "beam.soracom.io", "-p", "1883", "-t", "parking_spot", "-m", convertToJsonString(occupied)], stdout=subprocess.PIPE)
print(occupied)
```

### キル・スクリプト

Pythonスクリプトが適切に終了できるようにしなければなりません。ここでは

```js
close()
```

をユーザーが ^C コマンドでスクリプトを kill したときに呼び出される関数として定義します。ここで、センサーの測定値をクリーンアップすることができます。

```js
GPIO.cleanup()
```

.

```js
def close(signal, frame):
  print("Turning off ultrasonic distance detection...")
  GPIO.cleanup()
  sys.exit(0)
signal.signal(signal.SIGINT, close)
```

おめでとう、これで駐車スペースのステータスの更新を公開する python スクリプトが書けました。

サブスクライブ - Androidモバイルアプリ
------------------------

センサーがPubNubチャンネルにデータをパブリッシュすることに成功したので、駐車場の空き状況データを含むチャンネルにサブスクライブするようにモバイルアプリをセットアップする必要があります。

[PubNub Android SDKを](https://www.pubnub.com/docs/sdks/android)利用するには、まずモジュールbuild.gradleファイルに以下のgradle依存関係を追加する必要があります。

```js
implementation group: 'com.pubnub', name: 'pubnub-gson', version: '6.4.5'
```

次に、アプリがインターネットを使用できるようにするために、以下のAndroid Manifest Permissionsを追加します。

```js
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
```

このモバイルアプリでは、1つのアクティビティ（**MainActivity** クラス）を作成します。 このアクティビティには、3つのUI要素からなる基本的なビューが含まれます。

-   空車状況を表示するTextView
-   車のアイコンのImageView
-   駐車スペースアイコンのImageView

駐車スペースが空いているかどうかを表示するためにTextViewを使用し、駐車スペースの内側または外側に車のアイコンを表示するシンプルなアニメーションを用意します。駐車中の車のY位置は

```js
203f
```

で、駐車していない車のY位置は

```js
903f
```

.駐車場が空いているか埋まっているかを表示するために、アニメーションを使用して2つの間で位置を切り替えます。

![Smart Parking Lot](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jai/c49db6142edb3aba23c185ba1cc254d4/Screenshot_20180802-125832.png "Smart Parking Lot") [![Smart Parking Lot](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jak/13634e1cfbae33fbc5da29409018fe87/Screenshot_20180802-125822.png "Smart Parking Lot")](https://images.ctfassets.net/3prze68gbwl1/asset-17suaysk1qa1jaj/ac205dec3aff8b815d037ebb91ac8e53/Screenshot_20180802-125822.png)

まず、MainActivityクラスのフィールドを宣言します。

```js
PubNub pubNub;
TextView occupiedText;
ImageView car, parkingSpot;
float outsideCar = 903f;
float parkedCar = 203f;
```

次に、UI要素をインスタンス化します。

```js
findViewById()
```

メソッドでUI要素をインスタンス化します。

```js
onCreate()
```

メソッドでUI要素をインスタンス化します。**メイン・アクティビティのレイアウト・ファイルには**、以下のUIエレメントが適切なIDで含まれていることを確認する必要があります。私が選んだIDは

```js
occupiedText
```

,

```js
car
```

および

```js
parkingspot
```

.私のレイアウトファイル全体を見るには、[ここをクリックして](https://github.com/kaushikravikumar/Smart-Parking/blob/master/SmartParkingAndroid/app/src/main/res/layout/activity_main.xml)ください。

```js
occupiedText = findViewById(R.id.occupiedText);
car = findViewById(R.id.car);
parkingSpot = findViewById(R.id.parkingspot);
```

次に

```js
PubNub
```

インスタンスを作成し、AndroidアプリからPubNub APIを呼び出せるようにします。これを行うには、以下のコードを記述し、[PubNub Admin Consoleで](https://dashboard.pubnub.com/login)アプリを作成するときに生成した**Subscribe Keyと** **Publish Keyを**渡します。

```js
PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.setSubscribeKey("ENTER_SUBSCRIBE_KEY_HERE");
pnConfiguration.setPublishKey("ENTER_PUBLISH_KEY_HERE");
pnConfiguration.setSecure(true);
pubNub = new PubNub(pnConfiguration);
```

これで

```js
PubNub
```

インスタンスがインスタンス化されたので、センサーが駐車可否データを公開しているチャンネル**parking\_spotに**サブスクライブすることができます。これを行うには、メッセージがチャネルにパブリッシュされたときのコールバックリスナーを追加する必要があります。それから、実際にチャンネルを購読しなければならない。これを以下に示す。

```js
pubNub.addListener(new SubscribeCallback() {
      @Override
      public void status(PubNub pubnub, PNStatus status) {
      }
      @Override
      public void message(PubNub pubnub, PNMessageResult message) {
         // HANDLE MESSAGE
      }
      @Override
      public void presence(PubNub pubnub, PNPresenceEventResult presence) {
      }
  });
  pubNub.subscribe()
          .channels(Arrays.asList("parking_spot")) // subscribe to channels
          .execute();
```

次に、メッセージを処理するロジックを実装します。基本的には、駐車場の現在の稼働状況をチェックすることで、モバイルアプリのUIで駐車場の空き状況を切り替えたい。したがって、私たちのチャンネルに公開されたばかりのメッセージをチェックし、駐車場が現在利用可能なのか、それとも埋まっているのかを確認します。利用可能な場合は、ヘルパーメソッド

```js
carLeaveAnimation()
```

.占有されている場合は、ヘルパーメソッド

```js
carEnterAnimation()
```

.このように

```js
message()
```

メソッドの内部では次のようになります。

```js
final boolean occupied = message.getMessage().getAsJsonObject().get("occupied").getAsBoolean();
 runOnUiThread(new Runnable() {
     public void run() {
         if(occupied)
         {
             carEnterAnimation();
         }
         else
         {
             carLeaveAnimation();
         }
     }
 });
```

で

```js
carEnterAnimation()
```

では、単にtextviewにoccupiedと設定しています。また

```js
animate()
```

メソッドを呼び出し、そのY位置を駐車スペースに移動します（変数に格納されたY座標の値に移動します、

```js
parkedCar
```

).で

```js
carLeaveAnimation()
```

では、単にtextviewをavailableに設定し、車のimageviewの

```js
animate()
```

メソッドを呼び出し、Y位置を駐車スペースの外（Y座標の値、

```js
outsideCar
```

).

```js
private void carEnterAnimation()
{
    car.animate().y(parkedCar).setDuration(1500);
    occupiedText.setText("Occupied");
}
private void carLeaveAnimation()
{
    car.animate().y(outsideCar).setDuration(1500);
    occupiedText.setText("Vacant");
}
```

  
**埋め込みコンテンツが**このページで**利用できない**場合は、[https://www.youtube.com/embed/KySPa\_D2ne0?enablejsapi=1&origin=https%3A%2F%2Fwww.pubnub.com](https://www.youtube.com/embed/KySPa_D2ne0?enablejsapi=1&origin=https%3A%2F%2Fwww.pubnub.com)で見ることもできます。

以上でモバイルアプリは完成です！これで、センサーから駐車場の空き状況の更新を受け取ることができました。

アプリの起動
------

センサーを起動するには、Raspberry Piのターミナルからスクリプトのあるディレクトリに入ります。そして以下のコマンドを実行します。

```js
python sensor_publish.py
```

センサーがオンになり、距離測定値をチェックしていることがわかります。Androidモバイルアプリを実行すると、モバイルアプリのUIが更新され、駐車場のステータスが表示されます。

結論
--

おめでとうございます！これでシンプルなスマートパーキング[IoT](https://www.pubnub.com/solutions/iot-device-control/)アプリが完成しました。**完全なソースコードについては**、 **[ここをクリックして](https://github.com/PubNubDevelopers/Smart-Parking)**ください。PubNubとSoracomを統合することで、LTEを使用してRaspberry Piからリアルタイムでメッセージを送信するIoTアプリを構築しました。Wifiネットワークに制限される代わりに、私たちのスマートパーキングIoTアプリは非常にポータブルで屋外での使用に最適です。

[IoTダッシュボードのデモと](https://www.pubnub.com/demos/iot-dashboard/) [ダッシュボードに基づいたIoTチュートリアルも](https://www.pubnub.com/tutorials/iot-dashboard/)ご覧ください。

PubNubはあなたのお役に立ちますか？
====================

この記事は[PubNub.com](https://www.pubnub.com/blog/smart-parking-iot-simulation-with-realtime-space-monitoring/)に掲載されたものです。

PubNubのプラットフォームは、開発者がWebアプリ、モバイルアプリ、IoTデバイス向けにリアルタイムのインタラクティブ機能を構築、提供、管理できるように支援します。

私たちのプラットフォームの基盤は、業界最大かつ最もスケーラブルなリアルタイムエッジメッセージングネットワークです。世界15か所以上で8億人の月間アクティブユーザーをサポートし、99.999%の信頼性を誇るため、停電や同時実行数の制限、トラフィックの急増による遅延の問題を心配する必要はありません。

PubNubを体験
---------

[ライブツアーを](https://www.pubnub.com/tour/introduction/)チェックして、5分以内にすべてのPubNub搭載アプリの背後にある本質的な概念を理解する

セットアップ
------

[PubNubアカウントに](https://admin.pubnub.com/signup/)サインアップすると、PubNubキーに無料ですぐにアクセスできます。

始める
---

[PubNubのドキュメントは](https://www.pubnub.com/docs)、ユースケースや[SDKに](https://www.pubnub.com/docs)関係なく、あなたを立ち上げ、実行することができます。