Inteligentny system parkowania ze śledzeniem przestrzeni na żywo

PubNub Developer Relations - Jan 11 - - Dev Community

Nigdy wcześniej nie żyliśmy w czasach, w których każda "rzecz" mogła być bezproblemowo połączona przez Internet. Idea Internetu Rzeczy (IoT ) nieustannie przekształca nasz świat, prezentując innowacyjne rozwiązania wielu problemów przy użyciu architektury Pub/Sub sterowanej zdarzeniami. Na przykład, aby rozwiązać męczący problem ze znalezieniem miejsca parkingowego w zatłoczonych miejscach, parkingi zainstalowały elektroniczne pulpity nawigacyjne pokazujące na żywo, które miejsca są dostępne, subskrybując aktualizacje statusu publikowane z poszczególnych czujników na parkingu. Zbudowanie takiej aplikacji IoT może być trudne ze względu na szereg przeszkód.

Jedną z tych przeszkód jest hostowanie serwera zdolnego do obsługi wiadomości wysyłanych między aplikacją mobilną a urządzeniami czujnikowymi w czasie rzeczywistym. Inną jest obsługa sieci Wi-Fi zdolnej do obsługi każdego wbudowanego czujnika na inteligentnym parkingu.

Używając PubNub i Soracom obok siebie, deweloperzy mogą jednak szybko obejść te wyzwania. Dzięki platformie czasu rzeczywistego PubNub deweloperzy mogą łatwo tworzyć złożone rozwiązania IoT do monitorowania pojazdów, nie martwiąc się o żmudne zadania, takie jak hosting serwerów. Dodatkowo, dzięki Soracom Air i Soracom Beam, deweloperzy mogą łatwo tworzyć rozwiązania IoT, które wykorzystują LTE, zamiast restrykcyjnej sieci WFI.

Przegląd samouczka

W tym samouczku zbudujemy symulację inteligentnego parkowania przy użyciu Raspberry Pi i czujnika ultradźwiękowego do wykrywania, czy miejsce parkingowe jest zajęte czy wolne. Użyjemy Soracom Air do wysyłania wiadomości z czujnika do PubNub za pośrednictwem danych komórkowych. Następnie za pomocą interfejsu API PubNub Publish-Subscribe udostępnimy dane o parkowaniu na żywo wszystkim użytkownikom aplikacji mobilnej. Przedstawia to poniższy schemat.


Aby uzyskać pełny kod źródłowy, kliknij tutaj.


Smart Parking Lot

Aby zbudować to demo, będziesz potrzebować:

  1. Raspberry Pi (dowolna wersja)
  2. Płytka montażowa
  3. Czujnik ultradźwiękowy HC-SR04
  4. 1 żeńsko-żeński + 6 męsko-żeńskich przewodów połączeniowych
  5. 1 rezystor 1k Ω i 1 rezystor 2k Ω
  6. Karta MicroSD + przejściówka z MicroSD na SD
  7. Modem USB Huawei
  8. Karta SIM Soracom Air

Konfiguracja Raspberry Pi

1. Instalacja systemu operacyjnego Raspbian

Jeśli jeszcze tego nie zrobiłeś, upewnij się, że zainstalowałeś Raspbian OS na swoim Raspberry Pi. Aby to zrobić, najpierw zainstalujemy go lokalnie na naszym komputerze. Będzie to format obrazu dysku, więc będziemy musieli sflashować dysk przed jego użyciem. Możesz użyć programu Etcher, aby sflashować dysk na kartę microSD.

Smart Parking Lot

Gdy pliki systemu operacyjnego Raspbian znajdą się na naszym adapterze karty microSD, możemy wyjąć kartę microSD z adaptera, a następnie włożyć ją do dolnego gniazda naszego Raspberry Pi. Po zainstalowaniu systemu operacyjnego można teraz uruchomić Raspberry Pi, podłączając klawiaturę, mysz, monitor i źródło zasilania.

2. Konfiguracja czujnika

Smart Parking Lot

  1. Podłącz 3 nasze męskie i że ńskie przewody połączeniowe do czujnika ultradźwiękowego HC-SR04 w gniazdach VCC, Echo i GND. Podłącz jeden z naszych żeńskich i żeńskich przewodów połączeniowych do gniazda Trig czujnika.
  2. Podłącz przewód VCC do dodatniej szyny naszej płytki prototypowej, a przewód GND do szyny ujemnej.
  3. Podłącz GPIO 5V na Raspberry Pi do dodatniej szyny naszej płytki, a GPIO GND do szyny ujemnej.
  4. Podłącz przewód Trig do GPIO 23.
  5. Podłącz przewód Echo do pustej szyny na płytce prototypowej.
  6. Podłącz kolejną pustą szynę za pomocą rezystora 1k Ω. (Powodem, dla którego potrzebujemy rezystorów jest to, że możemy obniżyć napięcie wyjściowe, aby upewnić się, że nasz Raspberry Pi nie zostanie uszkodzony przez konfigurację czujnika).
  7. Następnie podłącz pustą szynę za pomocą rezystora 2k Ω do ujemnej szyny naszej płytki drukowanej, pozostawiając wolne miejsce. Jeśli nie masz rezystora 2k Ω, możesz utworzyć serię 2 rezystorów 1k Ω, jak pokazano na poniższym obrazku.IMG_20180731_151118-1
  8. W miejscu, które nam pozostało, użyjemy zworki męsko-żeńskiej , aby połączyć się z GPIO 24.

Gratulacje, zakończyliśmy konfigurację naszego czujnika ultradźwiękowego. Jeśli utknąłeś w konfiguracji czujnika, zapoznaj się z tym samouczkiem, aby uzyskać bardziej szczegółowe wyjaśnienie. Podczas budowania obwodu należy pamiętać, że na pustych szynach płytki prąd płynie poziomo, a na szynach dodatnich i ujemnych prąd płynie pionowo. Następnie skonfigurujemy PubNub i Soracom w naszej aplikacji IoT.

Konfiguracja PubNub

Najpierw utworzymy naszą aplikację w konsoli administracyjnej Pub Nub*(jest bezpłatna*). Po utworzeniu aplikacji w konsoli zobaczysz klucze publikowania i subskrypcji, których użyjemy w następnym kroku do połączenia PubNub i Soracom.

Konfiguracja Soracom

Zarejestruj kartę SIM

Przejdziemy do konsoli administratora Soracom. Tutaj klikniemy Zarejestruj kartę SIM i wprowadzimy cyfry ICCID i PUK, które można znaleźć z tyłu karty SIM Soracom Air.

imageedit_2_3979299183Smart Parking Lot

Konfiguracja modemu USB

Po zarejestrowaniu naszej karty SIM, wyjmiemy chip SIM (pokazany fioletowym kółkiem, które narysowałem wokół niego na powyższym obrazku). Następnie włożymy go do modemu USB Huawei. Upewnij się, że wsunąłeś kartę SIM do końca, prawą stroną do góry.

Smart Parking Lot

Aby nasze Raspberry Pi działało na danych komórkowych, po prostu podłączymy modem Huawei USB Stick do portu USB Raspberry Pi. Stałe niebieskie światło (nie miga) wskazuje, że modem pomyślnie odbiera dane 3g. Jeśli miga, oznacza to, że nadal próbuje się połączyć.

IMG_20180801_141334

Po zaświeceniu się niebieskiego światła musimy dodać nasz modem USB Stick do Menedżera sieci Raspberry Pi. Aby to zrobić, najpierw zainstaluj Network Manager na Raspberry Pi. W terminalu Raspberry Pi wpisz następujące polecenie.

sudo apt-get update && sudo apt-get install network-manager
Enter fullscreen mode Exit fullscreen mode

Następnie, aby podłączyć nasz modem USB Stick do naszego konta Soracom, musimy wpisać następujące polecenie z terminala Raspberry Pi. Zastąp i odpowiednimi danymi uwierzytelniającymi konta.

sudo nmcli con add type gsm ifname "*" con-name soracom apn soracom.io user <ENTER_USERNAME> password <ENTER_PASSWORD>
Enter fullscreen mode Exit fullscreen mode

Aby ta konfiguracja weszła w życie, musimy zrestartować nasze Raspberry Pi.

sudo reboot
Enter fullscreen mode Exit fullscreen mode

Teraz, aby upewnić się, że modem USB jest rozpoznawany przez menedżera sieci Raspberry Pi, wpisz:

ifconfig
Enter fullscreen mode Exit fullscreen mode

Powinieneś zobaczyć

ppp0
Enter fullscreen mode Exit fullscreen mode

(Twój modem USB). Następnie wpisz następujące 3 polecenia terminala, aby upewnić się, że pobrałeś skrypt ppp route metric Soracom i że skrypt jest uruchamiany za każdym razem, gdy modem USB jest podłączony lub ponownie uruchomiony.

sudo curl -o /etc/NetworkManager/dispatcher.d/90.set_ppp_route_metric https://soracom-files.s3.amazonaws.com/handson/90.set_ppp_route_metric
Enter fullscreen mode Exit fullscreen mode
sudo chmod +x /etc/NetworkManager/dispatcher.d/90.set_ppp_route_metric
Enter fullscreen mode Exit fullscreen mode
sudo /etc/NetworkManager/dispatcher.d/90.set_ppp_route_metric ppp0 up
Enter fullscreen mode Exit fullscreen mode

Teraz nasz modem USB Stick powinien być poprawnie skonfigurowany. Jeśli nadal nie możesz skonfigurować modemu USB Stick, upewnij się, że dokładnie przeczytałeś dokumentację Soracom.

Konfiguracja MQTT

MQTT (Mosquitto) to nazwa protokołu, którego będziemy używać do publikowania wiadomości na naszym kanale PubNub z aplikacji Raspberry Pi IoT. W konsoli administratora otworzymy łącze bocznego paska nawigacyjnego zatytułowane Grupy, aby dodać nową grupę. Nazwiemy tę nową grupę Beam-Soracom. W ustawieniach podstawowych tej nowej grupy klikamy na Soracom Beam. Tutaj utworzymy punkt wejścia MQTT. Upewnij się, że podczas tworzenia punktu wejścia MQTT wprowadzono następujące dane. Będziesz musiał określić typ miejsca docelowego jako PubNub. Tam, gdzie widzisz Credentials Set, dodamy nasze poświadczenia PubNub(Publish i Subscribe Key), aby umożliwić naszemu urządzeniu Soracom publikowanie wiadomości na naszym kanale PubNub.

IMG_20180801_141334

Następnie wybierzemy naszą zarejestrowaną kartę SIM w konsoli administratora i ustawimy jej grupę na tę, którą właśnie utworzyliśmy, o nazwie Beam-Soracom. Upewnij się, że kliknąłeś aktywuj na naszej zarejestrowanej karcie SIM, aby była aktywna i odbierała dane.

Teraz musimy zainstalować pakiet mosquitto-clients na naszym Raspberry Pi, abyśmy mogli korzystać z metody publikowania MQTT. W terminalu Raspberry Pi uruchom następujące polecenie.

sudo apt-get update && sudo apt-get install mosquitto-clients
Enter fullscreen mode Exit fullscreen mode

Po zainstalowaniu mosquitto-clients możemy przetestować nasze polecenie mosquitto_pub, którego użyjemy do opublikowania wiadomości na naszym kanale PubNub. Format naszego polecenia mosquitto_pub będzie następujący. Po -t wstawimy nazwę naszego kanału, parking_spot. A po -m wstawimy wiadomość testową "test". Podnieś widok debugowania w konsoli administratora PubNub. Po uruchomieniu poniższego polecenia w terminalu Raspberry Pi powinieneś zobaczyć, że wiadomość została pomyślnie opublikowana na naszym kanale PubNub.

mosquitto_pub -h beam.soracom.io -p 1883 -t parking_spot  -m "test"
Enter fullscreen mode Exit fullscreen mode

Smart Parking Lot

Teraz nasze urządzenie Soracom Air może z powodzeniem publikować wiadomości z naszego Raspberry Pi na naszym kanale PubNub. Dzięki tej konfiguracji jesteśmy gotowi do rozpoczęcia pisania kodu do publikowania z czujnika ultradźwiękowego i subskrybowania z aplikacji mobilnej na Androida.

Publikowanie - czujnik ultradźwiękowy - skrypt Python

Napiszemy nasz kod Pythona w skrypcie o nazwie sensor_publish.py (ten skrypt musi znajdować się wewnątrz Raspberry Pi!). Zacznij od zaimportowania niektórych modułów, których będziemy potrzebować w górnej części skryptu. Moduł RPI.GPIO pozwoli nam uzyskać dane z czujników. Moduł time pozwoli nam okresowo uzyskiwać odczyty z czujnika. Signal i sys pozwolą nam napisać naszą metodę, która zabije skrypt i przestanie odczytywać dane z czujnika, gdy użytkownik użyje polecenia ^ C. Subprocess i json pozwolą nam przeanalizować naszą wartość logiczną do odpowiedniego formatu JSON String i wysłać ją do naszego kanału PubNub.

import RPi.GPIO as GPIO
import time
import signal
import sys
import subprocess
import json
Enter fullscreen mode Exit fullscreen mode

Konfiguracja czujnika

Po zaimportowaniu naszych modułów musimy upewnić się, że nasz obiekt GPIO używa numerów pinów płytki Raspberry Pi. Zrobimy to za pomocą następującej linii.

GPIO.setmode(GPIO.BCM)
Enter fullscreen mode Exit fullscreen mode

Następnie musimy przypisać wartości do naszych pinów wejściowych i wyjściowych. Nasz pin wejściowy nazywa się ECHO, a nasz pin wyjściowy nazywa się TRIG. ECHO jest podłączone do pinu 18*(**GPIO 24), a TRIG do pinu 16(GPIO 23*), co można sprawdzić w konfiguracji Raspberry Pi. Musimy również zainicjować naszą zmienną

occupied
Enter fullscreen mode Exit fullscreen mode

której będziemy używać do śledzenia ostatnio zaktualizowanego statusu miejsca parkingowego. Zainicjujemy ją na False.

TRIG = 23
ECHO = 24
occupied = False
Enter fullscreen mode Exit fullscreen mode

Następnie zdefiniujemy naszą funkcję, która skonfiguruje nasz czujnik. Nazwiemy tę funkcję

setup_sensor()
Enter fullscreen mode Exit fullscreen mode

. Tutaj musimy zdefiniować, który pin jest naszym wejściem, a który wyjściem. Wywołamy tę funkcję później w naszej funkcji głównej.

def setup_sensor():
  GPIO.setup(TRIG, GPIO.OUT)
  GPIO.setup(ECHO, GPIO.IN)
Enter fullscreen mode Exit fullscreen mode

Uzyskanie odczytu odległości z czujnika

Użyjemy funkcji

get_distance()
Enter fullscreen mode Exit fullscreen mode

aby uzyskać dane dotyczące odległości obiektu od naszego czujnika. Funkcja ta wykona obliczenia dotyczące czasu, jaki sygnał impulsowy potrzebował, aby przejść i powrócić z obiektu. Wykorzystując czas, obliczy odległość od czujnika do obiektu.

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
Enter fullscreen mode Exit fullscreen mode

Publikowanie dostępności miejsc parkingowych

Będziemy publikować dostępność naszego miejsca parkingowego w głównej funkcji naszego skryptu Python. Będzie to funkcja wykonywana po uruchomieniu skryptu. Funkcja główna musi wykonać następujące czynności w kolejności.

  1. Konfiguracja czujnika
  2. Przeprowadzić wstępne sprawdzenie dostępności miejsca parkingowego
  3. Sprawdzić, czy status uległ zmianie (co 5 sekund): Jeśli się zmienił, opublikuj komunikat o nowym statusie. Zapisz ten status jako ostatni zaktualizowany status.

Aby skonfigurować czujnik, wywołamy funkcję, którą zdefiniowaliśmy wcześniej,

setup_sensor()
Enter fullscreen mode Exit fullscreen mode

. Następnie wykona ona wstępne sprawdzenie, czy miejsce parkingowe jest dostępne lub wolne. Zdefiniujemy metodę

initial_check()
Enter fullscreen mode Exit fullscreen mode

aby to zrobić.

Następnie będziemy mieć pętlę, która będzie wykonywana co 5 sekund w celu sprawdzenia nowego odczytu odległości samochodu. Jeśli odczyt odległości uzyskany przez funkcję

get_distance()
Enter fullscreen mode Exit fullscreen mode

jest większa niż 7 cm (długość miejsca parkingowego w moim modelu), możemy wywnioskować, że miejsce parkingowe jest wolne. Odległość, którą odbiera funkcja, jest w tym przypadku po prostu szumem. Jeśli jest mniejsza niż 7 cm, wiemy, że miejsce parkingowe jest zajęte przez samochód.

Aby zminimalizować koszty i zmaksymalizować wydajność, będziemy aktualizować status miejsca parkingowego tylko wtedy, gdy czujnik pokaże, że status zmienił się od ostatniego odczytu. Jest to pokazane poniżej:

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)
Enter fullscreen mode Exit fullscreen mode

Nasza funkcja

initial_check()
Enter fullscreen mode Exit fullscreen mode

przypisze naszą zmienną

occupied
Enter fullscreen mode Exit fullscreen mode

do aktualnego stanu miejsca parkingowego. Musimy to opublikować za pomocą modułu

subprocess
Enter fullscreen mode Exit fullscreen mode

który zaimportowaliśmy wcześniej. Dzięki temu modułowi jesteśmy w stanie uruchamiać polecenia terminala ze skryptu Pythona. Używając metody

Popen()
Enter fullscreen mode Exit fullscreen mode

po prostu przekazujemy tablicę ciągów z polecenia, tak jak wpisuje się je w terminalu. Po -m, chcemy przekazać wiadomość zakodowaną jako JSON String, z kluczem "occupied" i wartością zmiennej

occupied
Enter fullscreen mode Exit fullscreen mode

. Możemy to zrobić, wywołując naszą metodę pomocniczą

convertToJsonString()
Enter fullscreen mode Exit fullscreen mode

która pobiera wartość logiczną i konwertuje ją na wiadomość JSON String, którą możemy wysłać.

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)
Enter fullscreen mode Exit fullscreen mode
def convertToJsonString(occupied):
  dictionary_object = {
    "occupied": occupied
  }
  return json.dumps(dictionary_object)
Enter fullscreen mode Exit fullscreen mode

Wreszcie, wewnątrz naszej pętli, która jest wykonywana co 5 sekund w naszej głównej funkcji, będziemy mieli następujący kod. Spowoduje to przełączenie zajętej wartości logicznej, a następnie opublikowanie jej na naszym kanale parking_spot, jeśli różni się od ostatnio zaktualizowanego stanu.

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

Skrypt zabijania

Musimy również upewnić się, że nasz skrypt Pythona może zostać poprawnie zabity. Definiujemy

close()
Enter fullscreen mode Exit fullscreen mode

jako funkcję wywoływaną, gdy użytkownik zabije skrypt poleceniem ^C. W tym miejscu możemy wyczyścić nasze odczyty czujników za pomocą linii

GPIO.cleanup()
Enter fullscreen mode Exit fullscreen mode

.

def close(signal, frame):
  print("Turning off ultrasonic distance detection...")
  GPIO.cleanup()
  sys.exit(0)
signal.signal(signal.SIGINT, close)
Enter fullscreen mode Exit fullscreen mode

Gratulacje, napisaliśmy teraz skrypt Pythona, który publikuje aktualizacje statusu miejsca parkingowego.

Subskrybuj - aplikacja mobilna na Androida

Teraz, gdy nasz czujnik z powodzeniem publikuje dane do naszego kanału PubNub, musimy skonfigurować aplikację mobilną tak, aby była subskrybowana do kanału zawierającego dane o dostępności miejsc parkingowych.

Najpierw musimy dodać następujące zależności gradle do naszego pliku Module build.gradle, aby wykorzystać PubNub Android SDK.

implementation group: 'com.pubnub', name: 'pubnub-gson', version: '6.4.5'
Enter fullscreen mode Exit fullscreen mode

Następnie dodamy następujące uprawnienia manifestu Androida, aby umożliwić naszej aplikacji korzystanie z Internetu.

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Enter fullscreen mode Exit fullscreen mode

Dla tej aplikacji mobilnej zbudujemy jedną aktywność, klasę MainActivity . Ta aktywność będzie zawierać podstawowy widok składający się z 3 elementów interfejsu użytkownika.

  • TextView do podawania dostępności
  • ImageView dla ikony samochodu
  • ImageView dla ikony miejsca parkingowego

Użyjemy TextView do stwierdzenia, czy miejsce parkingowe jest dostępne i będziemy mieć prostą animację pokazującą ikonę samochodu wewnątrz miejsca parkingowego lub poza nim. Zaparkowany samochód będzie miał pozycję Y równą

203f
Enter fullscreen mode Exit fullscreen mode

a niezaparkowany samochód będzie miał pozycję Y równą

903f
Enter fullscreen mode Exit fullscreen mode

. Aby pokazać, czy miejsce parkingowe jest wolne, czy zajęte, będziemy przełączać jego pozycję między nimi za pomocą animacji.

Smart Parking Lot Smart Parking Lot

Najpierw zadeklarujemy pola naszej klasy MainActivity.

PubNub pubNub;
TextView occupiedText;
ImageView car, parkingSpot;
float outsideCar = 903f;
float parkedCar = 203f;
Enter fullscreen mode Exit fullscreen mode

Następnie utworzymy instancję elementów interfejsu użytkownika za pomocą metody

findViewById()
Enter fullscreen mode Exit fullscreen mode

wewnątrz metody

onCreate()
Enter fullscreen mode Exit fullscreen mode

metoda. Musimy upewnić się, że plik układu aktywności głównej zawiera następujące elementy interfejsu użytkownika z odpowiednimi identyfikatorami określonymi poniżej. Identyfikatory, które wybrałem to

occupiedText
Enter fullscreen mode Exit fullscreen mode

,

car
Enter fullscreen mode Exit fullscreen mode

oraz

parkingspot
Enter fullscreen mode Exit fullscreen mode

. Aby zobaczyć mój kompletny plik układu, kliknij tutaj.

occupiedText = findViewById(R.id.occupiedText);
car = findViewById(R.id.car);
parkingSpot = findViewById(R.id.parkingspot);
Enter fullscreen mode Exit fullscreen mode

Teraz musimy utworzyć instancję

PubNub
Enter fullscreen mode Exit fullscreen mode

abyśmy mogli wykonywać wywołania PubNub API z poziomu naszej aplikacji na Androida. Aby to zrobić, napiszemy następujący kod i przekażemy Subscribe Key i Publish Key, które wygenerowaliśmy podczas tworzenia aplikacji w PubNub Admin Console.

PNConfiguration pnConfiguration = new PNConfiguration();
pnConfiguration.setSubscribeKey("ENTER_SUBSCRIBE_KEY_HERE");
pnConfiguration.setPublishKey("ENTER_PUBLISH_KEY_HERE");
pnConfiguration.setSecure(true);
pubNub = new PubNub(pnConfiguration);
Enter fullscreen mode Exit fullscreen mode

Teraz, gdy utworzyliśmy instancję

PubNub
Enter fullscreen mode Exit fullscreen mode

możemy zasubskrybować kanał, do którego nasz czujnik publikuje dane o dostępności parkingu, parking_spot. Aby to zrobić, będziemy musieli dodać słuchacza wywołania zwrotnego, gdy wiadomość zostanie opublikowana na kanale. Następnie musimy zasubskrybować kanał. Jest to pokazane poniżej.

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();
Enter fullscreen mode Exit fullscreen mode

Następnie zaimplementujemy logikę obsługi wiadomości. Chcemy zasadniczo przełączać dostępność miejsca parkingowego w interfejsie użytkownika naszej aplikacji mobilnej, sprawdzając jego aktualny stan zajętości. Dlatego sprawdzimy wiadomość właśnie opublikowaną na naszym kanale, aby sprawdzić, czy miejsce parkingowe jest teraz dostępne, czy zajęte. W przypadku, gdy jest ono dostępne, wywołamy naszą metodę pomocniczą

carLeaveAnimation()
Enter fullscreen mode Exit fullscreen mode

. W przypadku, gdy jest zajęte, wywołamy naszą metodę pomocniczą

carEnterAnimation()
Enter fullscreen mode Exit fullscreen mode

. Tak więc wewnątrz naszej metody

message()
Enter fullscreen mode Exit fullscreen mode

mamy następującą metodę.

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

W

carEnterAnimation()
Enter fullscreen mode Exit fullscreen mode

po prostu ustawiamy widok tekstowy na zajęty. Wywołujemy również metodę

animate()
Enter fullscreen mode Exit fullscreen mode

na widoku obrazu samochodu i przesuwamy jego pozycję Y na miejsce parkingowe (do wartości współrzędnej Y przechowywanej w zmiennej,

parkedCar
Enter fullscreen mode Exit fullscreen mode

). W

carLeaveAnimation()
Enter fullscreen mode Exit fullscreen mode

po prostu ustawiamy widok tekstowy na dostępny i wywołujemy metodę

animate()
Enter fullscreen mode Exit fullscreen mode

na widoku obrazu samochodu, aby przesunąć jego pozycję Y poza miejsce parkingowe (do wartości współrzędnej Y),

outsideCar
Enter fullscreen mode Exit fullscreen mode

).

private void carEnterAnimation()
{
    car.animate().y(parkedCar).setDuration(1500);
    occupiedText.setText("Occupied");
}
private void carLeaveAnimation()
{
    car.animate().y(outsideCar).setDuration(1500);
    occupiedText.setText("Vacant");
}
Enter fullscreen mode Exit fullscreen mode

Jeśli osadzona zawartość nie jest dostępna na tej stronie, można ją również wyświetlić pod adresem https://www.youtube.com/embed/KySPa_D2ne0?enablejsapi=1&origin=https%3A%2F%2Fwww.pubnub.com.

To wszystko dla naszej aplikacji mobilnej! Teraz z powodzeniem odbiera aktualizacje z czujnika dotyczące dostępności naszego miejsca parkingowego.

Uruchamianie aplikacji

Aby uruchomić czujnik, wystarczy wejść do katalogu, w którym znajduje się skrypt z terminala Raspberry Pi. Następnie wykonaj następujące polecenie.

python sensor_publish.py
Enter fullscreen mode Exit fullscreen mode

Zobaczysz, że czujnik został włączony i sprawdza odczyty odległości. Uruchom aplikację mobilną na Androida i powinieneś zobaczyć, że interfejs użytkownika aplikacji mobilnej zostanie zaktualizowany i wyświetli status miejsca parkingowego.

Podsumowanie

Gratulacje! Stworzyliśmy teraz prostą aplikację Smart Parking IoT. Aby uzyskać pełny kod źródłowy, kliknij tutaj. Integrując PubNub i Soracom, stworzyliśmy aplikację IoT, która wykorzystuje LTE do wysyłania wiadomości w czasie rzeczywistym z Raspberry Pi. Zamiast być ograniczonym przez sieć Wi-Fi, nasza aplikacja Smart Parking IoT jest niezwykle przenośna i idealna do użytku na zewnątrz.

Zachęcamy również do zapoznania się z naszym demo pulpitu nawigacyjnego IoT i samouczkiem IoT opartym na tym pulpicie.

Jak PubNub może ci pomóc?

Ten artykuł został pierwotnie opublikowany na PubNub.com

Nasza platforma pomaga programistom tworzyć, dostarczać i zarządzać interaktywnością w czasie rzeczywistym dla aplikacji internetowych, aplikacji mobilnych i urządzeń IoT.

Fundamentem naszej platformy jest największa w branży i najbardziej skalowalna sieć przesyłania wiadomości w czasie rzeczywistym. Dzięki ponad 15 punktom obecności na całym świecie obsługującym 800 milionów aktywnych użytkowników miesięcznie i niezawodności na poziomie 99,999%, nigdy nie będziesz musiał martwić się o przestoje, limity współbieżności lub jakiekolwiek opóźnienia spowodowane skokami ruchu.

Poznaj PubNub

Sprawdź Live Tour, aby zrozumieć podstawowe koncepcje każdej aplikacji opartej na PubNub w mniej niż 5 minut.

Rozpocznij konfigurację

Załóż konto PubNub, aby uzyskać natychmiastowy i bezpłatny dostęp do kluczy PubNub.

Rozpocznij

Dokumenty PubNub pozwolą Ci rozpocząć pracę, niezależnie od przypadku użycia lub zestawu SDK.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .