Raspberry Pi Tutorial 1

Einrichten und C2D Nachrichten empfangen

Einleitung

In diesem Tutorial geht es darum, einen RaspberryPi 3 mit dem Clouddienst Microsoft Azure zu verbinden. Im ersten Teil des Tutorials werden wir einen Client auf dem RaspberryPi programmieren, der mit einem Azure IoT Hub verbunden wird und Cloud-To-Device Nachrichten empfangen kann.

Verwendete Hardware: Raspberry Pi 3

Voraussetzungen:

Dieses Tutorial geht davon aus, das Erfahrung mit Programmierung vorhanden sind, setzt aber keine Erfahrungen mit Raspbian, GPIO Mikroprozessoren (Pi, Arduino etc.) oder Python voraus.

Ziel:

Ziel ist es cloud-to-device Nachrichten mittels Microsoft Azure IoT Hub zu versenden, die vom Raspberry Pi angenommen werden und zu einer Reaktion (z.B. Veränderung des Zustands einer angeschlossenen LED) führen.

Beispiel Nutzungen:

– Smarthome System wie z.B. automatische Rolläden

– Ferngesteuerte Servomotoren für eine Webcam

– Einfache Wand montierte Informationstafel

Vorbereitung:

Raspberry Pi vorbereiten (wenn das Betriebssystem schon installiert ist, weiter bei Schritt 2)

Um das RaspberryPi nutzen zu können muss ein Betriebssystem installiert werden, dafür bietet sich Raspbian an, das speziell zu diesem Zweck entwickelt wurde. Um dieses Betriebssystem auf dem Pi zu installieren verwenden wir NOOBS, die New-Out-Of-Box-Software die auf der Raspberry Pi Website heruntergeladen werden kann.

Die .zip Datei muss auf die microSD Karte des Pis extrahiert werden.

Sollte das Raspberry Pi bereits mit vorinstalliertem NOOBS auf der microSD Karte gekommen sein, können sie dies überspringen.

Um die Installation am Pi ausführen zu können sollten sie Tastatur, Maus und einen Bildschirm anschließen. Wenn sie nun die SD-Karte mit NOOBS in den Slot des Pis stecken und ihn dann starten indem sie das Netzteil anschließen, sollte ein Fenster auftauchen, in dem Gefragt wird, welches Betriebssystem installiert werden soll. Wählen sie „Raspbian“ und installieren sie es.

Raspberry Pi aktualisieren

Die Installation wird einige Zeit in Anspruch nehmen. Wenn sie abgeschlossen ist, nehmen sie sich etwas Zeit um sich mit dem Startmenü vertraut zu machen und gucken sie insbesondere nach der Python2 IDLE. Im Neuesten Softwarepatch ist diese nicht mehr direkt im Startmenü zu finden. Mittels des Startmenü-Editors können sie die IDLE aber wieder zum Startmenü hinzufügen.

Bevor sie damit anfangen können neue Updates herunterzuladen müssen sie zunächst noch ihr Pi mit dem Internet verbinden, dafür können sie entweder ein LAN-Kabel nutzen oder ihr Wi-Fi.

Sobald sie Verbunden sind, schließen sie alle unnötigen Fenster und öffnen sie ein Teminal Fenster. Hier werden wir nun zwei Befehle eingeben.

sudo apt-get update

Dies wird ein paar Sekunden dauern, wenn das Terminal sie auffordert, das nächste Kommando einzugeben, schreiben sie:

sudo apt-get dist-upgrade

Das zweite Kommando updated ihr Raspbian image auf die aktuellste Version.

Erste Schritte:

Die iot-hub Bibliothek installieren

Wenn sie ihr Raspberry Pi richtig eingerichtet haben, müssen wir jetzt die IoTHub Bibliothek installieren. Dafür gibt es zwei Methoden; entweder besuchen sie Github (https://github.com/Azure-Samples/iot-hub-python-raspberrypi-client-app) und laden das repository als Zip herunter, oder sie können das repository via Terminal klonen.

sudo apt-get install git-core
git clone https://github.com/Azure-Samples/iot-hub-python-raspberrypi-client-app.git

um die Bibliothek zu kompilieren nutzen sie die Folgenden Kommandos (passen sie den Dateipfad an wenn nötig):

cd ./iot-hub-raspberrypi-client-app
sudo chmod u+x setup.sh
sudu ./setup.sh

Tipps:

– Sie können Verzeichnisse mittels *Joker wechseln, wenn sie keine Verzeichnisse mit ähnlichem Namen haben. Beispiel: „cd ./iot-*“ wird sie ins passende Verzeichnis bringen.

Das kompilieren der Bibliothek hat einen Ordner iothub_python erzeugt. Suchen sie diesen Ordner und suchen sie nach einem File mit dem Namen: iothub_client.so

Diese Datei müssen sie kopieren und in dem Ordner, in dem sie ihr späteres Programm schreiben wollen wieder einfügen, damit der Code funktioniert und die Klassen aus der Bibliothek verwendet werden können.

Anlegen des Geräts in IoTHub

Wenn sie bereits einen IoTHub erstellt haben, können sie hier weiter machen, ansonsten folgen sie bitte dem Tutorial ( XXX )

Öffnen sie ihren IoT Hub in ihrem Internet Browser und navigieren sie zum IoT Devices Reiter. In diesem können sie nun per klick auf das blaue „+ „ ein neues Gerät erzeugen.

IoT Device Reiter

Nach einem Klick auf das plus öffnet sich die Ansicht zum erstellen eines neuen Geräts, geben sie hier ihrem Gerät eine einzigartige ID und setzen sie das Häkchen bei Auto-generate-Keys. Zum Schluss bestätigen sie die Erstellung durch klicken auf save.

IoT Device Erzeugen

Das so erzeugt Gerät lässt sich nun in der Geräteansicht anwählen. Wenn das Gerät angewählt ist, öffnet sich eine neue Sicht, in der Informationen über das Gerät angezeigt werden. Wichtig ist hierbei der Primäre Verbindungsschlüssel, den wir für die spätere Verwendung noch brauchen werden

IoT Device Details

Den Code schreiben

Das Grundgerüst:

Jetzt, da sie mit den Vorbereitungen so weit fertig sind, wird es Zeit mit dem Code zu beginnen. Öffnen sie dazu die Python2 IDLE und erzeugen sie ein neues Dokument. Beginnen sie damit, die Imports zu übertragen:

 from iothub_client import IoTHubClient 
 from iothub_client import IoTHubClientError 
 from iothub_client import IoTHubTransportProvider 
 from iothub_client import IoTHubClientResult 
 from iothub_client import IoTHubMessage 
 from iothub_client import IoTHubMessageDispositionResult 
 from iothub_client import IoTHubError 
 from iothub_client import DeviceMethodReturnValue 
 import sys 
 import time
 import RPi.GPIO as GPIO 

Hiermit werden die Klassen der iothub Bibliothek verwendbar. Außerdem ermöglichen wir die spätere Nutzung der GPIO Ein-/Ausgänge für unsere Hardware.

Um das ganze schön und sauber zu halten erzeugen wir einige Variablen, die wir später verwenden wollen. Darunter ist z.B. der Connection String unseres IoT Geräts, diese ist die Primary-Connection_String die wir im vorherigen Schritt gefunden haben.

CONNSTR="HostName=xxx;DeviceId=xxx;SharedAccessKey=xxx" 
CLIENT = 0 
MSGID = 0

Wenn sie diesen Code laufen lassen, sollte es keine Fehlermeldungen geben (wenn sie bereits eine Kopie von iothub_client.so mit im selben Ordner haben.) Da der Code aber ansonsten noch keine Funktion hat, schießt es sich sofort wieder.

Der Client

Da wir einen ordentlichen und übersichtlichen Code erzeugen wollen, erstellen wir für die unterschiedlichen Funktionalitäten jeweils eine eigene Funktion. Als erstes müssen wir einen IoTHubClient initialisieren. Dafür erstellen wir die Funktion setupClient folgendermaßen:

def setupClient():   
  global CONNSTR   
  client = IoTHubClient(CONNSTR, IoTHubTransportProvider.MQTT)  
  client.set_option("product_info", "RPI-Python")     
  return client

Damit wir diese Funktion aber auch ausführen können, müssen wir unserem Programm noch eine Main() Funktion hinzufügen, die als Startpunkt verwendet wird. In dieser erzeugen wir mittels setupClient() einen Client und speichern ihn in der dafür vorgesehen Variable ab.

def main():   
  global CLIENT   
  CLIENT = setupClient()   
  SENDING = True

Jetzt haben wir einen Client, der mit IoT Hub verbunden ist, damit dieser nun aber auch Funktionalität hat müssen wir eine Callback Methode für erhaltene Nachrichten erstellen und dem Client übergeben.

Diese Callback Methode wird immer dann aufgerufen, wenn der Azure Server eine Nachricht an das Gerät sendet. Im Moment hat sie noch keine Funktionalität, außer dem Anzeigen der gesendeten Nachricht auf der Konsole.

def gotMail(message, context):
  message_buffer = message.get_bytearray() 
  size = len(message_buffer) 
  msg = message_buffer[:size].decode("utf-8") 
  print("Server says: %s " % (msg)) 
  return IoTHubMessageDispositionResult.ACCEPTED 

Damit der Client nun auch von dieser Methode weiß, müssen wir diese übergeben, dafür ändern wir die setupClient() indem wir in der Zeile mit global hinter einem Komma noch gotMail einfügen und vor dem Return folgende Zeile Code ergänzen:

client.set_message_callback(gotMail,0)

Nun haben wir eine Funktionierende Methode und einen Server, der Nachrichten empfangen kann, damit sich das Programm aber nicht sofort schließt, müssen wir ans Ende des Ausgeführten Codes noch eine Dauerschleife hinzufügen.

print("Starte IoT Hub Client ...") 
main() 
while True: 
  time.sleep(1)  

Cloud-to-Device Nachrichten

Um zu Testen, ob unser Code auch tatsächlich funktioniert, starten wir diesen und wenden uns dann wieder dem Azure Portal zu, da wir aus diesem heraus Nachrichten an unser Raspberry Pi schicken können. Dafür müssen wir wieder in die Device Detail Ansicht unseres Geräts wechseln und dort auf den „Message to Device“ Knopf Drücken. Haben wir dies getan, öffnet sich die Nachrichten Ansicht, in der wir nun einige Eingabe Felder vorfinden.

Im Textfeld Message Body kann der zu übermittelnde Text geschrieben werden. Mit einem klick auf „Send Message“ wird diese an das Gerät gesendet. Als weitere Optionen kann man auch noch einen Key und ein Value versenden.

C2D Nachrichten Ansicht

Reaktion auf Nachrichten

Wie bereits am Anfang des Tutorials erwähnt wollen wir unserem Code nun ein bisschen Funktionalität hinzufügen, indem wir eine LED mittels Nachrichten von Azure steuern. Dafür müssen wir zunächst eine LED an unser Raspberry Pi anschließen. Dafür wählen wir in diesem Fall den GPIO Pin6 und verbinden diesen mit einer LED, und einem in reihe geschalteten 120 Ohm Widerstand, von dem aus das ganze dann an den GPIO Ground angeschlossen wird.

LED Schaltung

Damit das so Funktioniert müssen wir den Nummerierungsmodus einstellen und den Pin als Output initialisieren. Dafür verwenden wir folgenden Code, den wir über dem Ausgeführten Code hinzufügen müssen

# Nummerierungs Modus 
GPIO.setmode(GPIO.BCM) 
# GPIO Pin 6 als Output setzen 
GPIO.setup(6, GPIO.OUT)

Nun müssen wir noch Funktionen für das an und ausschalten der LED schreiben, die wir später, wenn wir auf eine Nachricht reagieren aufrufen können. In diesen Funktionen wird der Status der LED geändert.

def turnLightOn(): # Regardless of state, turn the light on     
  global LIGHTON       
  # Remember the set state     
  LIGHTON = True       
  # Set pin 6 to HIGH voltage (3V)   
  GPIO.output(6, GPIO.HIGH)     
  print ("LED on!") 

def turnLightOff(): # Regardless of state, turn the light off     
  global LIGHTON      
  #Remember the set state     
  LIGHTON = False      
  # Set pin 6 to LOW voltage (0V)     
  GPIO.output(6, GPIO.LOW)     
  print ("LED off.") 

def toggleLight(): # Toggle the light state from one to the other         
  global LIGHTON     
  print ("Toggling...")     
  if LIGHTON:         
    turnLightOff() # if ON then TURN OFF     
  else:         
    turnLightOn()  # if OFF then TURN ON

Mit diesen Funktionen können wir nun einfach die LED steuern. Da wir auf die Nachrichten von Azure reagieren wollen müssen wir die gotMail Methode entsprechend anpassen. Dafür nutzen wir einfach eine Verkettung von if, elif, else Bedingungen bei denen wir die Nachricht mit vorgegebenen Zeichenfolgen vergleichen.
Nach
msg = message_buffer[:size].decode(„utf-8“)
fügen wir nun ein:

if msg == "on" or msg == "LED on":               
  turnLightOn()
elif msg == "off" or msg == "LED off":               
  turnLightOff()         
elif msg =="toggle" or msg == "LED toggle":  
  toggleLight()

Dieser Code sorgt dafür, dass nun immer die passende Funktion aufgerufen wird, wenn die empfangene Nachricht den entsprechenden Text enthält. Damit haben sie nun eine fernsteuerbare LED an ihrem Raspberry Pi und den ersten Teil des Tutorials beendet.

Weitere Tutorials

Schnellstart Tutorial
Tutorial 1: C2D Nachrichten empfangen
Tutorial 2: Temperatur Sensor und D2C