Intelligentes Parksystem mit Live-Platzverfolgung
Published: 2024-01-11 12:18:56

Nie zuvor haben wir in einer Ära gelebt, in der jedes "Ding" nahtlos über das Internet miteinander verbunden werden konnte. Die Idee des [Internet der Dinge (IoT)](https://www.pubnub.com/solutions/iot-device-control/) hat unsere Welt kontinuierlich verändert, indem sie innovative Lösungen für zahlreiche Probleme mit einer **ereignisgesteuerten Pub/Sub-Architektur** bietet. Um beispielsweise das mühsame Problem der Parkplatzsuche in überfüllten Parkhäusern zu lösen, haben Parkhäuser elektronische Live-Dashboards installiert, die anzeigen, welche Plätze noch frei sind, indem sie Status-Updates abonnieren, die von einzelnen Sensoren in einem Parkhaus veröffentlicht werden. Die Entwicklung einer solchen IoT-App kann aufgrund einer Reihe von Hürden eine Herausforderung darstellen.

Eine dieser Hürden ist das Hosting eines Servers, der in der Lage ist, Nachrichten zwischen der mobilen App und den Sensorgeräten in Echtzeit zu verarbeiten. Eine weitere Hürde ist das Hosting eines WiFi-Netzwerks, das jedes einzelne eingebettete Sensorgerät auf dem intelligenten Parkplatz unterstützen kann.

Durch den parallelen Einsatz von **PubNub** und **Soracom** können Entwickler diese Herausforderungen jedoch schnell umgehen. Mit der Echtzeit-Plattform von PubNub können Entwickler problemlos [komplexe IoT-Lösungen](https://www.pubnub.com/solutions/iot-device-control/) für die [Fahrzeugüberwachung](https://www.pubnub.com/solutions/transport-delivery/) [aufbauen](https://www.pubnub.com/solutions/iot-device-control/), ohne sich um lästige Aufgaben wie das Hosting von Servern kümmern zu müssen. Darüber hinaus können Entwickler mit [Soracom Air](https://www.soracom.io/products/air/) und [Soracom Beam](https://www.soracom.io/products/beam/) problemlos IoT-Lösungen entwickeln, die LTE anstelle eines restriktiven WFI-Netzwerks nutzen.

Tutorial Übersicht
------------------

In diesem Tutorial bauen wir eine Smart Parking Simulation mit einem Raspberry Pi und einem Ultraschallsensor, der erkennt, ob ein Parkplatz besetzt oder frei ist. Wir werden Soracom Air verwenden, um Nachrichten vom Sensor über Mobilfunkdaten an PubNub zu senden. Mithilfe der Publish-Subscribe-API von PubNub werden wir dann die Live-Parkdaten sofort für alle mobilen Benutzer der App verfügbar machen. Dies ist im folgenden Diagramm dargestellt.

* * *

**Für den vollständigen Quellcode [klicken Sie bitte hier](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)

Um diese Demo zu erstellen, benötigen Sie:

1.  Raspberry Pi (beliebige Version)
2.  Breadboard
3.  HC-SR04 Ultraschallsensor
4.  1 weiblich-weiblich + 6 männlich-weiblich Überbrückungsdrähte
5.  1 **1k Ω-Widerstand** und 1 **2k Ω-Widerstand**
6.  MicroSD-Karte + MicroSD-SD-Adapter
7.  Huawei USB-Stick-Modem
8.  Soracom Air Sim Karte

Raspberry Pi-Einrichtung
------------------------

### **1\. Raspbian OS Installation**

Wenn Sie es noch nicht getan haben, sollten Sie das Betriebssystem Raspbian auf Ihrem Raspberry Pi installieren. Zu diesem Zweck installieren wir es zunächst lokal auf unserem Computer. Da es sich um ein Disk-Image handelt, müssen wir die Diskette flashen, bevor wir sie verwenden können. Sie können [Etcher](https://www.balena.io/etcher/) verwenden, um die Diskette auf Ihren microSD-Kartenadapter zu flashen.

[![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)

Sobald sich die Raspbian-Betriebssystemdateien auf unserem microSD-Kartenadapter befinden, können wir die microSD-Karte aus dem Adapter entfernen und in den unteren Steckplatz unseres Raspberry Pi einsetzen. Nach der Installation des Betriebssystems können Sie nun den Raspberry Pi starten, indem Sie eine Tastatur, eine Maus, einen Monitor und eine Stromquelle anschließen.

### 2\. Sensor konfigurieren

[![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.  Stecken Sie 3 unserer **männlich-weiblichen Jumperdrähte** in den **HC-SR04 Ultraschallsensor** in die **Steckplätze VCC, Echo und GND.** Stecken Sie einen unserer **weiblich-weiblichen Jumperdrähte** in den **Trig-Steckplatz** des Sensors.
2.  Stecken Sie das **VCC-Kabel** in die **positive Schiene** unseres Breadboards und das **GND-Kabel** in die **negative Schiene**.
3.  Verbinden Sie **GPIO 5V** auf dem Raspberry Pi mit der **positiven Schiene** unseres Breadboards und **GPIO GND** mit der **negativen Schiene**.
4.  Verbinden Sie den **Trig-Draht** mit GPIO **23**.
5.  Verbinden Sie den **Echo-Draht** mit einer **leeren Schiene** auf dem Breadboard.
6.  Verbinde eine weitere leere Schiene mit einem **1k Ω Widerstand**. (Der Grund, warum wir Widerstände benötigen, ist, dass wir die Ausgangsspannung verringern können, um sicherzustellen, dass unser Raspberry Pi nicht durch die Sensorkonfiguration beschädigt wird)
7.  Verbinden Sie dann eine leere Schiene mit einem **2k Ω-Widerstand** mit der negativen Schiene unseres Breadboards und lassen Sie dabei eine Lücke. Wenn Sie keinen 2k Ω-Widerstand haben, können Sie eine Reihe von 2 1k Ω-Widerständen herstellen, wie in der folgenden Abbildung gezeigt.[![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.  In der verbleibenden Lücke werden wir einen **Überbrückungsdraht mit Stecker und Buchse** verwenden, um eine Verbindung zu **GPIO 24** herzustellen.

Herzlichen Glückwunsch, wir haben die Konfiguration unseres Ultraschallsensors nun abgeschlossen. Wenn Sie mit der Konfiguration des Sensors nicht weiterkommen, finden Sie in diesem [Tutorial](https://thepihut.com/blogs/raspberry-pi-tutorials/hc-sr04-ultrasonic-range-sensor-on-the-raspberry-pi) eine ausführlichere Erklärung. Denken Sie beim Aufbau Ihrer Schaltung daran, dass der Strom auf den leeren Schienen [des Breadboards](https://en.wikipedia.org/wiki/Breadboard) horizontal und auf den positiven und negativen Schienen des Breadboards vertikal fließt. Als nächstes werden wir PubNub und Soracom in unserer IoT-App einrichten.

PubNub-Einrichtung
------------------

Als erstes erstellen wir unsere App in der [PubNub Admin Console](https://dashboard.pubnub.com/login)**(sie ist kostenlos**). Nach der Erstellung der App in der Konsole sehen Sie die Veröffentlichungs- und Abonnementschlüssel, die wir im nächsten Schritt verwenden werden, um PubNub und Soracom zu verbinden.

Soracom Einrichtung
-------------------

### **SIM-Karte registrieren**

Gehen Sie nun zur [Soracom Admin Console](https://console.soracom.io/). Hier klicken wir auf **SIM registrieren** und geben die **ICCID-** und **PUK-Ziffern** ein, die Sie auf der Rückseite Ihrer **Soracom Air Sim-Karte** finden.

[![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 Modem Konfiguration

Nachdem wir unsere SIM-Karte registriert haben, entfernen wir den SIM-Chip (auf dem Bild oben mit einem lila Kreis umrandet). Dann setzen wir ihn in das **Huawei USB Stick Modem** ein. Vergewissern Sie sich, dass Sie die SIM-Karte ganz hineinschieben, und zwar mit der richtigen Seite nach oben.

[![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)

Um unseren Raspberry Pi mit Mobilfunkdaten zu versorgen, stecken wir den [Huawei USB Stick Modem](https://consumer.huawei.com/en/routers/e3372/specs/) einfach in den USB-Port des Raspberry Pi. Ein **durchgehendes blaues Licht** (nicht blinkend) zeigt an, dass das Modem erfolgreich 3g-Daten empfängt. Wenn es blinkt, bedeutet das, dass es noch versucht, eine Verbindung herzustellen.

[![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)

Sobald das blaue Licht dauerhaft leuchtet, müssen wir unser USB-Stick-Modem zum Netzwerkmanager des Raspberry Pi hinzufügen. Installieren Sie dazu zunächst den Network Manager auf dem Raspberry Pi. Geben Sie im Terminal Ihres Raspberry Pi Folgendes ein.

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

Um unser USB-Stick-Modem mit unserem Soracom-Konto zu verbinden, müssen wir den folgenden Befehl in unser Raspberry Pi-Terminal eingeben. Ersetzen Sie **<ENTER\_USERNAME>** und **<ENTER\_PASSWORD>** durch Ihre jeweiligen Zugangsdaten.

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

Damit diese Konfiguration in Kraft tritt, müssen wir unseren Raspberry Pi neu starten.

```js
sudo reboot
```

Um sicherzustellen, dass Ihr USB-Modem vom Netzwerkmanager des Raspberry Pi erkannt wird, geben Sie Folgendes ein:

```js
ifconfig
```

Sie sollten ein

```js
ppp0
```

(Ihr USB-Modem) angezeigt werden. Geben Sie dann die folgenden 3 Terminalbefehle ein, um sicherzustellen, dass Sie das ppp route metric-Skript von Soracom heruntergeladen haben und dass das Skript jedes Mal ausgeführt wird, wenn das USB-Modem eingesteckt oder neu gestartet wird.

```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
```

Jetzt sollte unser USB-Stick-Modem richtig konfiguriert sein. Wenn Sie bei der Konfiguration des USB-Stick-Modems immer noch nicht weiterkommen, lesen Sie bitte die [Soracom-Dokumente](https://github.com/soracom/handson/wiki/1.3.-USB-Dongle-configuration-tutorial-(SIM-pre-registered)) sorgfältig durch.

### MQTT-Einrichtung

[**MQTT**](https://www.pubnub.com/guides/mqtt/) (Mosquitto) ist der Name des Protokolls, das wir verwenden werden, um Nachrichten an unseren PubNub-Kanal von der Raspberry Pi IoT App zu veröffentlichen. In der Admin-Konsole öffnen wir die seitliche Navigationsleiste mit dem Link Gruppen, um **eine neue Gruppe hinzuzufügen**. Wir werden diese neue Gruppe **Beam-Soracom** nennen. Unter Grundeinstellungen für diese neue Gruppe klicken Sie auf **Soracom Beam**. Hier werden wir einen **MQTT Entry Point** erstellen. Stellen Sie sicher, dass Sie bei der Erstellung des [MQTT-Einstiegspunktes](https://www.pubnub.com/blog/what-is-mqtt-use-cases/) folgende Angaben gemacht haben. Sie müssen den Destination Type als **PubNub** angeben. Unter **Credentials Set** fügen wir unsere [PubNub-Credentials](https://admin.pubnub.com/#/register)**(Publish und Subscribe Key**) hinzu, damit unser Soracom-Gerät Nachrichten in unserem PubNub-Kanal veröffentlichen kann.

[![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)

Anschließend wählen wir unsere registrierte SIM-Karte in der Admin-Konsole aus und setzen ihre Gruppe auf die soeben erstellte Gruppe **Beam-Soracom**. Vergewissern Sie sich, dass Sie auf unserer registrierten SIM-Karte auf **aktivieren** geklickt haben, damit sie aktiv ist und Daten empfängt.

Nun müssen wir das **mosquitto-clients** Paket auf unserem Raspberry Pi installieren, damit wir die MQTT Veröffentlichungsmethode nutzen können. Führen Sie im Terminal des Raspberry Pi den folgenden Befehl aus.

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

Nach der Installation von mosquitto-clients können wir unseren **mosquitto\_pub-Befehl** testen, mit dem wir eine Nachricht auf unserem PubNub-Kanal veröffentlichen werden. Das Format unseres mosquitto\_pub-Befehls sieht wie folgt aus. Nach **\-t** fügen wir den Namen unseres Channels ein, **parking\_spot**. Und nach **\-m** fügen wir eine Testnachricht "test" ein. Rufen Sie die Debug-Ansicht in der PubNub Admin-Konsole auf. Sobald Sie den unten stehenden Befehl auf dem Terminal des Raspberry Pi ausführen, sollten Sie sehen, dass die Nachricht erfolgreich in unserem PubNub-Kanal veröffentlicht wurde.

```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)

Jetzt ist unser Soracom Air Device in der Lage, erfolgreich Nachrichten von unserem Raspberry Pi auf unserem PubNub-Kanal zu veröffentlichen. Jetzt können wir mit dem Schreiben des Codes beginnen, um Nachrichten vom Ultraschallsensor zu veröffentlichen und von der mobilen Android-App zu abonnieren.

Veröffentlichen - Python-Skript für den Ultraschallsensor
---------------------------------------------------------

Wir schreiben unseren Python-Code in ein Skript namens **sensor\_publish.py** (dieses Skript muss sich im Raspberry Pi befinden!). Beginnen Sie damit, einige der Module zu importieren, die wir am Anfang des Skripts benötigen. Das Modul **RPI.GPIO** ermöglicht es uns, Daten von den Sensoren zu erhalten. Mit dem Modul **time** können wir in regelmäßigen Abständen Messwerte von den Sensoren abrufen. **Signal** und **sys** ermöglichen es uns, unsere Methode zu schreiben, die das Skript beendet und das Lesen der Sensordaten stoppt, wenn der Benutzer den Befehl ^C verwendet. **Subprocess** und **json** ermöglichen es uns, unser Boolean in das entsprechende JSON-String-Format zu parsen und es an unseren [PubNub-Kanal](https://www.pubnub.com/docs/general/channels/overview) zu senden.

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

### Sensor-Einrichtung

Nachdem wir unsere Module importiert haben, müssen wir sicherstellen, dass unser GPIO-Objekt die Pin-Nummern des Raspberry Pi Boards verwendet. Wir werden dies mit der folgenden Zeile tun.

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

Anschließend müssen wir unseren Eingangs- und Ausgangspins Werte zuweisen. Unser Eingangspin heißt **ECHO** und unser Ausgangspin heißt **TRIG**. ECHO ist mit Pin 18**(GPIO 24**) und TRIG mit Pin 16**(GPIO 23**) verbunden, wie Sie an Ihrem Raspberry Pi überprüfen können. Außerdem müssen wir unsere

```js
occupied
```

initialisieren, die wir verwenden werden, um den zuletzt aktualisierten Status des Parkplatzes festzuhalten. Wir werden sie auf False initialisieren.

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

Als Nächstes definieren wir unsere Funktion, die unseren Sensor einrichtet. Wir nennen diese Funktion

```js
setup_sensor()
```

. Hier müssen wir festlegen, welcher Pin unser Eingang und welcher unser Ausgang ist. Wir werden diese Funktion später in unserer Hauptfunktion aufrufen.

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

### Ablesen der Sensorentfernung

Wir verwenden die Funktion

```js
get_distance()
```

um die Daten zu erhalten, wie weit ein Objekt von unserem Sensor entfernt ist. Diese Funktion führt eine Berechnung durch, wie lange das Impulssignal brauchte, um vom Objekt zu gehen und zurückzukommen. Anhand der benötigten Zeit wird die Entfernung zwischen dem Sensor und dem Objekt errechnet.

```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
```

### Veröffentlichung der Verfügbarkeit von Parkplätzen

Wir werden die Verfügbarkeit unseres Parkplatzes in der Hauptfunktion unseres Python-Skripts veröffentlichen. Dies ist die Funktion, die ausgeführt wird, sobald das Skript gestartet wird. Die Hauptfunktion muss die folgenden Aktionen der Reihe nach ausführen.

1.  Einrichten des Sensors
2.  Eine erste Prüfung der Verfügbarkeit des Parkplatzes durchführen
3.  Prüfen, ob sich der Status geändert hat (alle 5 Sekunden): Wenn er sich geändert hat, wird eine Meldung über den neuen Status veröffentlicht. Speichern Sie diesen Status als den neuen, zuletzt aktualisierten Status.

Um den Sensor einzurichten, rufen wir die Funktion auf, die wir zuvor definiert haben,

```js
setup_sensor()
```

. Als Nächstes wird eine erste Prüfung durchgeführt, um festzustellen, ob der Parkplatz verfügbar oder frei ist. Wir definieren die Methode

```js
initial_check()
```

um dies zu tun.

Anschließend wird alle 5 Sekunden eine Schleife ausgeführt, um den neuen Entfernungswert des Fahrzeugs zu überprüfen. Wenn der mit der Funktion

```js
get_distance()
```

ermittelte Abstand größer als 7 cm ist (die Länge des Parkplatzes in meinem Modell), dann können wir daraus schließen, dass der Parkplatz frei ist. Die ermittelte Entfernung ist in diesem Fall einfach nur Rauschen. Ist sie kleiner als 7 cm, dann wissen wir, dass der Parkplatz von einem Auto belegt ist.

Um die Kosten zu minimieren und die Effizienz zu maximieren, wird der Status des Parkplatzes nur aktualisiert, wenn der Sensor anzeigt, dass sich der Status seit der letzten Messung geändert hat. Dies ist unten dargestellt:

```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)
```

Unsere

```js
initial_check()
```

Funktion wird unsere Variable

```js
occupied
```

den aktuellen Status des Parkplatzes zu. Wir müssen dies mit Hilfe des

```js
subprocess
```

Modul veröffentlichen, das wir zuvor importiert haben. Mit diesem Modul können wir Terminalbefehle aus einem Python-Skript heraus ausführen. Mit der Methode

```js
Popen()
```

übergeben wir einfach ein Array von Zeichenketten aus dem Befehl, so wie man ihn in ein Terminal eingeben würde. Nach **\-m** wollen wir die Nachricht kodiert als JSON-String übergeben, mit dem Schlüssel "occupied" und dem Wert der Variablen

```js
occupied
```

. Wir können dies tun, indem wir unsere Hilfsmethode

```js
convertToJsonString()
```

aufruft, die einen booleschen Wert in eine JSON-String-Nachricht umwandelt, die wir senden können.

```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)
```

Schließlich wird in unserer Schleife, die alle 5 Sekunden in unserer Hauptfunktion ausgeführt wird, der folgende Code eingefügt. Damit wird der boolesche Besetzt-Status umgeschaltet und dann in unserem **parking\_spot-Kanal** veröffentlicht**,** wenn er sich von seinem zuletzt aktualisierten Status unterscheidet.

```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)
```

### Skript beenden

Wir müssen auch sicherstellen, dass unser Python-Skript ordnungsgemäß beendet werden kann. Wir definieren

```js
close()
```

als die Funktion, die aufgerufen wird, wenn ein Benutzer das Skript mit dem Befehl ^C beendet. Hier können wir unsere Sensormesswerte mit der folgenden Zeile bereinigen

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

.

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

Herzlichen Glückwunsch, wir haben jetzt ein Python-Skript geschrieben, das den Status des Parkplatzes veröffentlicht.

Abonnieren - Android Mobile App
-------------------------------

Nun, da unser Sensor erfolgreich Daten an unseren PubNub-Kanal veröffentlicht, müssen wir die mobile App so einrichten, dass sie den Kanal mit den Daten zur Parkplatzverfügbarkeit abonniert.

Um das [PubNub Android SDK](https://www.pubnub.com/docs/sdks/android) nutzen zu können, müssen wir zunächst die folgenden gradle-Abhängigkeiten in unsere Modul build.gradle-Datei einfügen [.](https://www.pubnub.com/docs/sdks/android)

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

Als nächstes fügen wir die folgenden Android Manifest Permissions hinzu, damit unsere App das Internet nutzen kann.

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

Für diese mobile App werden wir eine Activity, die **MainActivity-Klasse** , erstellen, die eine Basisansicht mit 3 UI-Elementen enthalten wird.

-   TextView für die Angabe der Verfügbarkeit
-   ImageView für das Auto-Symbol
-   ImageView für das Parkplatz-Symbol

Wir werden die TextView verwenden, um anzugeben, ob der Parkplatz verfügbar ist, und wir werden eine einfache Animation haben, die das Autosymbol innerhalb oder außerhalb des Parkplatzes zeigt. Das geparkte Auto hat eine Y-Position von

```js
203f
```

und das nicht geparkte Auto hat eine Y-Position von

```js
903f
```

. Um zu zeigen, ob der Parkplatz frei oder besetzt ist, schalten wir seine Position mit Hilfe einer Animation zwischen den beiden Positionen um.

![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)

Zunächst deklarieren wir die Felder unserer MainActivity-Klasse.

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

Dann instanziieren wir die UI-Elemente mit der Methode

```js
findViewById()
```

innerhalb der Methode unserer Aktivität

```js
onCreate()
```

Methode. Wir müssen sicherstellen, dass die **Layout-Datei der Hauptaktivität** die folgenden UI-Elemente mit den entsprechenden IDs wie unten angegeben enthält. Die von mir gewählten Id's sind

```js
occupiedText
```

,

```js
car
```

, und

```js
parkingspot
```

. Um meine vollständige Layout-Datei zu sehen, [klicken Sie hier.](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);
```

Nun müssen wir unsere Instanz

```js
PubNub
```

Instanz instanziieren, damit wir die PubNub-API von unserer Android-App aus aufrufen können. Dazu schreiben wir den folgenden Code und übergeben den **Subscribe Key** und **Publish Key**, die wir beim Erstellen der App in der [PubNub Admin Console](https://dashboard.pubnub.com/login) generiert haben.

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

Nun, da wir unsere Instanz instanziiert haben

```js
PubNub
```

Instanz instanziiert haben, können wir den Channel **parking\_spot** abonnieren, auf dem unser Sensor Daten zur Parkverfügbarkeit veröffentlicht. Dazu müssen wir einen Callback-Listener hinzufügen, der anzeigt, wenn eine Nachricht im Kanal veröffentlicht wurde. Dann müssen wir den Kanal tatsächlich abonnieren. Dies ist unten dargestellt.

```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();
```

Anschließend implementieren wir die Logik für die Verarbeitung der Nachricht. Wir wollen im Wesentlichen die Verfügbarkeit des Parkplatzes in unserer mobilen App-UI umschalten, indem wir seinen aktuellen Belegungsstatus überprüfen. Wir werden also die soeben auf unserem Kanal veröffentlichte Nachricht überprüfen, um festzustellen, ob der Parkplatz nun verfügbar oder belegt ist. Wenn er verfügbar ist, rufen wir unsere Helper-Methode

```js
carLeaveAnimation()
```

. Wenn er belegt ist, rufen wir unsere Hilfsmethode

```js
carEnterAnimation()
```

. Somit haben wir innerhalb unserer

```js
message()
```

Methode haben wir also das Folgende.

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

In

```js
carEnterAnimation()
```

setzen wir einfach die Textansicht auf "besetzt". Wir rufen auch die

```js
animate()
```

Methode für die Bildansicht des Autos auf und verschieben seine Y-Position in die Parklücke (auf den Y-Koordinatenwert, der in der Variable,

```js
parkedCar
```

). In

```js
carLeaveAnimation()
```

setzen wir die Textansicht einfach auf "available" und rufen die Methode

```js
animate()
```

Methode auf, um die Y-Position des Fahrzeugs außerhalb der Parklücke zu verschieben (auf den Wert der Y-Koordinate,

```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");
}
```

  
**Wenn der eingebettete Inhalt** auf dieser Seite **nicht verfügbar ist**, kann er auch unter [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) angesehen werden.

Das war's für unsere mobile App! Jetzt empfängt sie erfolgreich Updates vom Sensor über die Verfügbarkeit unseres Parkplatzes.

App starten
-----------

Um den Sensor zu starten, geben Sie im Terminal des Raspberry Pi einfach das Verzeichnis an, in dem sich Ihr Skript befindet. Führen Sie dann den folgenden Befehl aus.

```js
python sensor_publish.py
```

Sie werden sehen, dass Ihr Sensor jetzt eingeschaltet ist und die Entfernungsmessungen überprüft. Starten Sie die mobile Android-App und Sie sollten sehen, dass die Benutzeroberfläche der mobilen App aktualisiert wird und den Status des Parkplatzes anzeigt.

Fazit
-----

Herzlichen Glückwunsch! Wir haben nun eine einfache Smart Parking [IoT-App](https://www.pubnub.com/solutions/iot-device-control/) erstellt. **Für den vollständigen Quellcode [klicken Sie bitte hier](https://github.com/PubNubDevelopers/Smart-Parking)**. Durch die Integration von PubNub und Soracom haben wir eine IoT-App gebaut, die LTE nutzt, um Echtzeit-Nachrichten vom Raspberry Pi zu senden. Anstatt durch ein WLAN-Netzwerk eingeschränkt zu sein, ist unsere Smart Parking IoT-App extrem mobil und perfekt für den Einsatz im Freien geeignet.

Sehen Sie sich auch unsere [IoT-Dashboard-Demo](https://www.pubnub.com/demos/iot-dashboard/) und unser [IoT-Tutorial an, das auf diesem Dashboard basiert](https://www.pubnub.com/tutorials/iot-dashboard/).

Wie kann PubNub Ihnen helfen?
=============================

Dieser Artikel wurde ursprünglich auf [PubNub.com](https://www.pubnub.com/blog/smart-parking-iot-simulation-with-realtime-space-monitoring/) veröffentlicht.

Unsere Plattform hilft Entwicklern bei der Erstellung, Bereitstellung und Verwaltung von Echtzeit-Interaktivität für Webanwendungen, mobile Anwendungen und IoT-Geräte.

Die Grundlage unserer Plattform ist das größte und am besten skalierbare Echtzeit-Edge-Messaging-Netzwerk der Branche. Mit über 15 Points-of-Presence weltweit, die 800 Millionen monatlich aktive Nutzer unterstützen, und einer Zuverlässigkeit von 99,999 % müssen Sie sich keine Sorgen über Ausfälle, Gleichzeitigkeitsgrenzen oder Latenzprobleme aufgrund von Verkehrsspitzen machen.

PubNub erleben
--------------

Sehen Sie sich die [Live Tour](https://www.pubnub.com/tour/introduction/) an, um in weniger als 5 Minuten die grundlegenden Konzepte hinter jeder PubNub-gestützten App zu verstehen

Einrichten
----------

Melden Sie sich für einen [PubNub-Account](https://admin.pubnub.com/signup/) an und erhalten Sie sofort kostenlosen Zugang zu den PubNub-Schlüsseln

Beginnen Sie
------------

Mit den [PubNub-Dokumenten](https://www.pubnub.com/docs) können Sie sofort loslegen, unabhängig von Ihrem Anwendungsfall oder [SDK](https://www.pubnub.com/docs)