Programmierung und Konfiguration des Pi

Ein wesentlicher Teil bei der Umsetzung des Projekts ist die Entwicklung des Python-Skript. Zusätzlich muss der Pi noch dementsprechend eingerichtet werden, dass das Skript dauerhaft im Hintergrund läuft. Im letzten Abschnitt befindet sich der vollständige Programmcode als Anhang.

Die Programmierung des Python Skripts:

Der inhaltiche Teil des von mir entwickelten Skripts besteht aus mehreren Teilen:

  1. Abrufen und Verarbeiten von Wetterdaten aus dem Internet.
  2. Umsetzung der Wetterdaten in verschiedenen Kategorien zur Ansteuerung der LEDs.
    1. Wetterlage anhand der WetterID
    2. Temperatur
    3. Windstärke und -richtung
  3. Einrichten und Ansteuern des LED-Streifens.

Dabei sind nicht alle diese drei Teile direkt so im Skript wiederzufinden. Vielmehr ist es so, dass die grundlegende Konfiguration des LED-Streifens zu Beginn passieren kann. Die explizite Ansteuerung der einzelnen LEDs erfolgt jedoch direkt innerhalb der jeweiligen Abschnitt, die die jeweiligen Informationen verarbeiten. Im Folgenden soll mein Code und wie ich dahin gelangt bin, nun so gut wie möglich Schritt für Schritt erklärt werden. Hier werde ich zudem immer kurze Code-Schnipsel zur Erklärung einfügen, die jedoch nicht vollständig sind und immer nur einen kleinen Teil des Programmcodes darstellen. Zusätzlich zur hin angebrachten Kommentierung ist auch der Code selbst so umfangreich kommentiert, dass er gut gelesen und nachvollzogen werden kann.

1. Abrufen und Verarbeiten von Wetterdaten aus dem Internet:

Ich habe mich dazu entschieden, die Wetterdaten von https://openweathermap.org/ zu beziehen. Nach einer kurzen Registrierung bietet diese Seite immer aktuelle und umfangreiche Wetterdaten zu über 200.000 Städten weltweit. Die Wetterdaten können via API einfach abgerufen und als JSON-Container leicht in Python verarbeitet werden. Mit dem kostenlosen Account sind bis zu 60 Abrufe pro Minute möglich, was für unsere Nutzung ausreichend ist und theoretisch eine sekündliche Aktualisierung ermöglicht.

Zur Abfrage dieser Wetterdaten kann direkt eine URL aufgerufen werden, die zwei flexible Teile enthält. Die Stadt, für die das Wetterabgeragt werden soll und den individuell generierten API-Schlüssel, der einem nach der Registrierung zur Verfügung gestellt wird. Daraus bauen wir nun also die gesamte URL, die dann zur Abfrage der Daten via API genutz wird, was für Oldenburg dann in etwa so aussieht:

API_key = "1a535be72b10f3c678749359a8a35050"
standort = "Oldenburg"
API_anfrage_url = "http://api.openweathermap.org/data/2.5/weather?q="+standort+",de&APPID="+API_key

Um die zur Verfügung gestellten Daten verarbeiten zu können verwende ich das Paket requests das in Python auf dem PI bereits vorinstalliert ist. Die Abfrage der Daten erfolgt dann mit wetterdaten_anfrage = requests.get(API_anfrage_url) anhand der zuvor generierten URL.

Mit wetterdaten = wetterdaten_anfrage.json() kann dieser Datencontainer dann lesbar gemacht werden und es wird ein einfacher Zugriff ermöglicht. Um die Struktur dieser Daten zu sehen, reicht es die URL direkt im Browser zu öffnen (BspLink). Dort ist leicht zu erkennen, dass es sich um eine einfache Listenstruktur handelt, in der direkt auf einzelne Elemente zugegriffen werden kann und Bspw. mit wetter_id = wetterdaten['weather'][0]['id'] die aktuelle WetterID abgerufen werden kann oder mit temperatur = wetterdaten['main']['temp'] die aktuelle Temperatur.

Dabei sind je nach Daten, die genutz werden sollen, unterschiedliche Dinge zu beachten. Die WetterID liefert zum Beispiel einen Zahlenwert, der die aktuelle Wettersituation genau beschreibt (der Code 800 steht z. B. für klaren Himmel). Eine Ausführliche Erklärung zu allen möglichen Wetter-IDs findet sich auf https://openweathermap.org/weather-conditions. Insgesamt bietet OpenWeather auf ihrer Webseite umfangreiche Dokumentationen und Hilfen zur Verwendung der Wetterdaten, jedoch nur in englischer Sprache. Genaueres zur Umsetzung und Verwendung der für dieses Projekt relevanten Daten folgt nun in den jeweiligen Abschnitten.

2. Umsetzung der Wetterdaten in verschiedenen Kategorien zur Ansteuerung der LEDs

Da die Wetterstation in unserer Uhr drei wesentliche Wetterinformationen darstellen können soll, müssen wir auch die entsprechenden Daten aus den aktuellen Wetterdaten herausfiltern und in eine Ansteuerung der LEDs umsetzen.

2.1. Wetterlage anhand der WetterID

Wie bereits erwähnt, befindet sich auf https://openweathermap.org/weather-conditions eine vollständiger Liste, möglicher WetterIDs. Diese sind zudem in Gruppen sortiert, sodass bspw. die Gruppe 2xx für verschiedene Arten von Gewitter steht. Auch wenn unsere Uhr zwar sehr detailiert die Wetterlage anzeigen kann, bietet die WetterID eine noch genauere Abstufung, als von uns gewünscht ist. Daher verwenden wir zur Abfrage immer ganze Bereiche von verschiednen IDs. Hier die Abfrage für die verschiedenen Arten von Gewitter, die unsere Uhr später anzeigen können soll:

if wetter_id < 210:
print("Gewitter mit Regen")
elif wetter_id < 230:
print("Gewitter ohne Regen")
elif wetter_id < 300:
print("Gewitter mit Nieseln")

Der Anzeigebereich für die Wettersymbole auf unserer Uhr besteht ja aus vier Bereichen: Sonne, Wolke, Nebel und verschiedene kleine Niederschlag-Symbole. Zur Beleuchtung der Symbole verwenden wir ja LEDs, die beliebige Farben darstellen können, was dazu führt, dass wir mit den Farben noch die verständlichkeit der Symbole erhöhen können. Dafür definieren wir uns zunächst die Farben die wir später benötigen:

wolkenfarbe = Color(100, 100, 100)
regenfarbe = Color(0, 0, 255)
blitzfarbe = Color(150, 255, 0)
schneefarbe = Color(255, 255, 150)
nebelfarbe = Color(50, 50, 50)

Damit die Abfragen übersichtlicher sind, habe ich in diesen Funktionen die Ansteuerung der entsprechenden LEDs je nach Wetterlage in eigene Funktionen ausgelagert. Hier als Beispiel die Funktion, die die Wolke beleuchtet:

def wolkenAnzeigen():
#Funktion zum Anzeigen der LEDs, die die Wolke beleuchten.
LEDStreifen.setPixelColor(9, wolkenfarbe)
LEDStreifen.setPixelColor(10, wolkenfarbe)
LEDStreifen.setPixelColor(11, wolkenfarbe)
LEDStreifen.setPixelColor(12, wolkenfarbe)
LEDStreifen.setPixelColor(13, wolkenfarbe)

(Eine genauere Erklärung, wie die Funktion LEDStreifen.setPixelColor() arbeitet werde ich unten im 3. Abschnitt anführen. Dies setzt auch eine initiale Einrichtung des LED-Streifens voraus, ohne die die Funktion nicht funktioniert.)

Die vollständige Abfrage inkl. Ansteuerung der LEDs bspw. für „Gewitter mit Regen“ sieht dann so aus:

if wetter_id >= 230 and wetter_id < 300:
wolkenAnzeigen()
regenAnzeigen(5)
blitzeAnzeigen()

Eine kleine Besonderheit bei den Wettersymbolen bildet bei unserer Uhr die Sonne. Diese ist das Symbol für einen klaren Himmel. Jedoch gibt es möglicheweise auch in der Nacht klaren Himmel, weswegen ich mich dazu entschieden habe, bei klarem Himmel bei Nacht, dieses Symbol in einer anderen Farbe zu beleuchten. Dazu war es zudem notwendig, die aktuelle Uhrzeit und die Zeitpunkte vom Sonnenauf und -untergang abzufragen. Diese Informationen bekommen wir zum einen aus dem Modul time von Python und zum anderen direkt aus den Wetterdaten:

zeit = int(time.time())
sonnenaufgang = wetterdaten['sys']['sunrise']
sonnenuntergang = wetterdaten['sys']['sunset']

2.2. Temperatur

Die Temperaturanzeige ist eine der einfachsten Umsetzungen in diesem Programm. OpenWeather liefert die Temperatur in °Kelvin, weswegen diese zuerst umgerechnet werden muss in °Celsius, was lediglich einfache Ergänzung bei der Abfrage benötigt:

temperatur = wetterdaten['main']['temp'] - 273.15

Da nun die Temperatur in °Celsius vorliegt und ich auf der Uhr genau eine LED pro Grad vorgesehen habe, ist es einfach diesen Wert nun auf dem LED-Streifen anzuzeigen. Da ich eine sowohl eine möglichst große Range von Temperaturen ermöglichen wolle, als auch eine leicht verständliche Temperaturanzeige kreieren wollte und der Platz auf der Uhr begrenzt ist, entschied ich mich bei negativen Temperaturen einfach die Farbe von rot zu blau zu welchseln. Temperaturen direkt bei 0 Grad werden zudem dargestellt, imdem die erste LED hellweiß leuchtet. Hier die for-Schleife, die solange LEDs-Beleuchtet, bis die aktuelle Temperatur (gerundet) erreicht ist:

farbepositiv = Color(0, 255, 0)
if temperatur >= 0.5:
#Darstellung von Temperaturen ueber 0. Bis maximal 35 Grad Celsius.
for i in range(34, min(int(round(temperatur,0))+34, 69)):
LEDStreifen.setPixelColor(i, farbepositiv)

Eine kleine Besonderheit bei der Temperatur ist zudem, dass die Skala „nur“ bis 35 °C geht. Da Temperatur unter -35 °C oder über 35 °C jedoch äußert selten und ggf. auch gefährlich sind, werden die LEDs der gesammten Uhr in einem solchen Fall auf maximale Helligkeit gestellt, um den Betrachter zu warnen. Diese Abfrage wird bereits bei der Einrichtung des LED-Streifens zu Beginn des Skripts getätigt.

2.3. Windstärke und -richtung

Dieser Abschnitt besteht aus zwei Parametern: Der Windstärke und der Windrichtung. Aus den Wetterdaten kann direkt die Windstärke in Metern pro Sekunde, sowie die Windrichtung als Gradangabe von Norden ausgehend abgerufen werden. Da ich im folgenden Programm mit den Windgeschwindigkeiten in Km/h rechnen möchte, muss dieser Wert zunächst mit windkmh = wetterdaten['wind']['speed'] * 3.6 umgerechnet werden. Für die Darstellung der Windstärke sind auf der Uhr pro Windrichtung vier seperate Segmente vorgesehen. Daher teilen wir die möglichen Windgeschwindigkeit in Bereiche ein und legen eine Farbe fest, in denen diese später leuchten sollen:

windLEDAnzahl = int(round(windkmh/20,0))
windfarbe = Color(220, 80, 80)

Um die Range dabei weiter zu erhöhen, können die vier Segmente zudem bei besonders hohen Windgeschwindigkeiten in anderen Farben leuchten. Auf diese Weise können windgeschwindigkeiten von 0 bis 120 Km/h in 20 Km/h Schritten dargestellt werden.

Der Zweite Faktor der berücksichtigt werden muss, ist die Windrichtung, da diese festlegt, welche der Anzeigepfeile auf der Uhr angestreuert werden. Die Zahl die aus den Wetterdaten hierzu extrahiert wird liefert die genaue Windrichtung von Norden an im Uhrzeigersinn gezählt und ist in Grad eingeteilt. Da diese Unterteilung für unsere Anzeige zu genau ist, teilen wir sie in acht Bereiche ein. Auf diese Weise können wir die gängigsten Windrichtungen auf der Uhr anzeigen. Dies kann analog zur WIndgeschwindigkeit durch eine einfache Skalierung realisiert werden:

windrichtungsLED = int(round(float(windrichtung)/45,0))

Abfragen mit for-Schleifen, die die LEDs der Windanzeige ansteuern könnten dann beispielsweise so aussehen. Hierbei werden ähnlich zur Temperatur nach und nach die LEDs beleuchtet, die auf der entsprechenden Anzeige sind.

if abs(windrichtungsLED) == 1:
for i in range(0, windLEDAnzahl*2-1):

LEDStreifen.setPixelColor(int(70.5-(windrichtungsLED*3.5)+
(i*windrichtungsLED)), windfarbe)

Da dies jedoch für jede Kategorie eine Abfrage benötigt, kann man zur Optimierung auch alle Abfragen in einer for-Schleife realisieren, die dann wie folgt aussieht:

if 5 > windLEDAnzahl >= 1:
#Ansteuerung der LEDs zur Anzeige des Windes.
for i in range(0, windLEDAnzahl*2-1):
LEDStreifen.setPixelColor(int(72.5+((abs(windrichtungsLED)-1)*8)-(windrichtungsLED/abs(windrichtungsLED*3.5)+(i*windrichtungsLED/abs(windrichtungsLED))), windfarbe)

Diese for-Schleife ist auf den ersten Blick nicht so leicht zu verstehen, macht jedoch das gleich, wie die obige for-Schleife, mit der Erweiterung, dass sie die Windrichtung mit einbezieht. Dabei macht sie sich zu nutze, dass die LEDs für die verschiedenen Windrichtungen alle hintereinander auf dem LED-Streifen liegen. Außerdem wurden für diese Funktion die jeweils entgegen gesetzten Windrichtungen (Süden/Norden) auch mit entgegengesetzten Werten (1/-1) codiert. Auf diese Weise gelten die Richtungspfeile am Ende der jeweiligen anzeige immer als Ausgangspunkt und von diesen aus werden dann entsprechend der Windstärke viele LEDs beleuchtet.

Analog zu den gefährlichen Temperaturen wird auch bei starkem Sturm (Windgeschwindigkeit ab 100 Km/h) die Helligkeit der gesamten Uhr als Warnung auf das Maximum gestellt.

Eine Besonderheit bei der Verwendung der Winddaten ist, dass unter Umständen kein Wind gemessen werden kann, wenn dieser zu schwach weht. In diesem Fall enthalten die abgefragten Wetterdaten auch keine Windrichtung. Daher ist es wichtig, einen möglichen Exception bei der Abfrage der Windrichtung aus den Wetterdaten abzufangen, falls die Daten fehlen und daher die Abfrage schief läuft. Dies ist in Python wie folgt zu realisieren:

try:
windrichtung = wetterdaten['wind']['deg']
except:
#Falls keine Windrichtung angegeben wird, wird kein Wind angezeigt.
windrichtung = -1

In diesem Sonderfall wird zudem die Windrichtung auf -1 gesetzt, sodass der Sonderfall später behandelt werden kann.

3. Einrichten und Ansteuern des LED-Streifens

Im vorherigen Abschnitt wurde bereits die methode LEDStreifen.setPixelColor() mehrfach verwendet. Diese stellt die wichtigste Methode zum Zugriff auf einzelne LEDs des LED-Streifens dar. Bevor die Methode setPixelColor() jedoch auf das Objekt LEDStreifen angewendet werden kann, muss dieses zuerst erstellt werden. Also von Anfang an:

In meinem Programmcode verwende ich das Modul neopixel zum Ansteuern der LEDs. Dieses Modul ist auf dem PI bereits vorinstalliert und enthält auch ein paar Beispiel-Skripte zum Testen und Ansteuern eines LED-Streifens. Diese Beispiele sind zu finden unter /home/pi/rpi_ws281x/python/examples/.

3.1. Die Voreinstellungen

Der erste wichtige Schritt zum Einrichten des LED-Streifens ist das setzen einiger Voreinstellungen.

LED_COUNT = 102 # Anzahl der LEDs auf dem angesteuerten Streifen.
LED_PIN = 18 # GPIO, an dem der LED-Streifen angeschlossen ist. LED_FREQ_HZ = 800000 # LED Signal-Frequenz in Hertz.
LED_DMA = 10 # DMA Kanal für das Ansteuerungssignal.
LED_BRIGHTNESS = 50 # Helligkeit des Streifens von 0 bis 255.
LED_INVERT = False # True um das Signal zu invertieren.
LED_CHANNEL = 0 # Auf '1' stellen, bei GPIOs 13, 19, 41, 45 or 53.

Neben einigen Standardwerten ist hier vor allem das Einstellen des LED_COUNT wichtig, um die Anzahl der zu verwenden LEDs auf dem Streifen einzustellen. Außerdem muss bei LED_PIN die Nummer des GPIO angegeben werden, an den die Steuerungsleitung des LED-Streifens angeschlossen ist. Mit LED_BRIGHTNESS kann zudem die gesamte Helligkeit des Streifens reduziert werden. Insgesamt sind die von uns verwendeten LEDs sehr hell, daher drossele ich im Normalfall die Helligkeit insgesamt auf 50. Wird der Wert auf 255gesetzt, können alle LEDs in der maximalen Helligkeit leuchten und können nur individuell, direkt bei der Ansteuerung reduziert werden. (siehe unten)

Diese Einstellung kann nur zu Beginn erfolgen, bevor der Streifen initialisiert wird. Daher müssen auch die Abfragen (Bei extremen Temperaturen oder extremem Strum), die oben bereits erwähnt wurden, die die Helligkeit des gesammten Streifens beeinflussen, an dieser Stelle getätigt werden.

Anschließend kann der Streifen initialisiert werden, indem ein Objekt angelegt wird, dem die zuvor eingestellten Parameter übergeben werden:

LEDStreifen = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
LEDStreifen.begin()

Von jetzt an kann die bereits erwähnte Methode setPixelColor() auf den LEDStreifen angewendet werden, die einzelne LEDs ansteuert. Dazu bekommt sie zwei Parameter übergeben: Die Nummer der LED und die Farbe, in der die LED leuchten soll. Die LEDs sind auf dem Streifen durchnummeriert von 0 bis zum Ende des Streifens (entsprechend den obigen Einstellungen sollte dies LED_COUNT - 1 sein). Bei uns demnach von 0 bis 101. Die Farbe wird dabei als Color(R, G, B) übergeben. Wobei R = Rot, G = Grün und B = Blau ist. Jede dieser Variablen kann dabei Werte zwischen 0 und 255 annehmen. Da jede LED auf dem Streifen eigentlich aus drei LEDs besteht, also einer pro Farbe, werden diese damit individuell angesteuert und die Höhe der Zahl gibt lediglich an, wie hell die jeweilige LED leuchten soll. Zum Beispiel liefert Color(0, 0, 255) ein sattes Blau, wärend Color(150, 255, 0) ein Sonnengeld liefert. Auch hier ist es daher nochmal möglich die Helligkeit der einzelnen LED zu regulieren.

Betrachten wir als Beispiel die Codezeilen, die dafür sorgen sollen, dass bei einer Temperatur von ca. 0 °C die erste LED der Temperaturskala in einem hellen weiß leuchtet:

farbenullgrad = Color(255, 255, 255)
if -0.5 < temperatur <0.5:
LEDStreifen.setPixelColor(34, farbenullgrad)

Dies bedeutet also, dass die LED mit der Nr. 34 angesteuert wird und in der Farbe Color(255, 255, 255), also weiß leuchten soll.

Wenn alle LEDs angesteuert wurden, die Leuchten sollen muss noch eine Abschließende Methode aufgerufen werden, die dafür sorgt, dass die ganzen getätigten Einstellungen und Befehle an der LED-Streifen übermittelt werden:

LEDStreifen.show()

Diese Funktion schließt die Ansteuerung des LED-Streifens ab. Da wir damit auch die letzte Zeile unseren Programms geschrieben haben, endet hiermit auch der Abschnitt zur Programmierung in Python.

Konfiguration des PI zum automatischen Ausführen des Python-Skripts

Zum automatischen Ausführen des Programms verwende ich crontap. Dies ist ein kleines Skript, dass regelmäßige automatisierte Aufrufe organisiert. Damit kann man sowohl Befehle für den Autostart, als auch regelmäßige Aufrufe in Abhängigkeit von der Zeit organisieren. Der Aufruf von der crontap erfolgt mit sudo crontab -e. Dies ruft ein Dokument auf, in dem zeilenweise Befehle, die sogenannten cron, notiert werden können. Dabei gibt der erste Block den Aufrufrythmus an, wärend dahinter der auszuführende Befehl notiert wird. Daneben kann noch notiert werden, wo eine etwaige Ausgabe landen soll. Die Zeile für einen minütlichen Ausführung unseres Skript sieht dann wie folgt aus:

* * * * * sudo python /home/pi/wetterabfrage.py > /home/pi/wetter.log

Die fünf Sterne im ersten Abschnitt besagen dabei, dass das Skript in jeder Minute, in jeder Stunde, an jedem Tag, in jedem Monat und an jedem Wochentag ausgeführt werden soll. Eine Notation für eine Ausführung alle 2 Minuten, nur am Freitag, würde dann entsprechend mit */5 * * * Fri notiert.

sudo python /home/pi/wetterabfrage.py enthält den Pfad, wo das Skript liegt und wie es ausgeführt werden soll. Dabei ist zu beachten, dass unser Skript nur funktioniert, wenn es mit Admin-Rechten ausgeführt wird. Daher muss dort dass erste Wort sudo stehen.

> /home/pi/wetter.log bewirkt, dass die von unserem Skript generierten print-Ausgaben in einer Logdatei gespeichert werden. Dies ist nützlich bei der Fehlersuche, falls etwas schiefgeht.

Da wir eine minütliche Ausführung des Skripts vorgesehen haben, ist eine zusätzliche Ausführung beim Systemstart nicht mehr notwendig. Das anschließende Starten des Browsers zur Darstellung der Bilder im digitalen Bilderrahmen dauert deutlich länger als eine Minute, weshalb dieser Zeitraum immer ausreicht, um bereits die erste Ausführung des Skript mit crontab abzudecken, sodass die Wetteranzeige auch ohne Autostart schnell online geht.

Der Vollständige Programmcode:

Das folgende Programm enthält das komplette Skript, dass in dieser Form genauso auf dem Raspberry Pi läuft, der in der Uhr verbaut ist. Enhalten sind ebenfalls alternative Abfragen, die leichter verständlich sind, als die kompakten Formeln. Besonders für Anfänger ist es zu empfehlen, zuerst diese auskommentierten Abschnitte genauer anzusehen, um die Funktionsweise der Wetterdaten zu verstehen.

# Dieses Programm fragt die aktuellen Wetterdaten von OpenWeather.org ab.
# Von den Wetterdaten werden die WetterID, Temperatur und Winddaten verwendet.
# Anhand dieser Daten wird ein LED-Streifen (102 LEDs) angesteuert.
# Dieser LED-Streifen zeigt dann auf einer Wanduhr die entsprechenden Wetterdaten an.
#
# Erstellt wurde das Skript von Dirk Stalhut im Rahmen eines Seminars
# an der Carl von Ossietzky Universität Oldenburg.

import time
import requests 
from neopixel import *

API_key = "1a535be72b10f3c678749359a8a35050"
standort = "Oldenburg"
API_anfrage_url = "http://api.openweathermap.org/data/2.5/weather?q="+standort+",de&APPID="+API_key

wetterdaten_anfrage = requests.get(API_anfrage_url)

#Ausgabe des Statuscodes (wenn 200, alles okay):
print(wetterdaten_anfrage.status_code)

# ------------------------------------------------------------------
# ----------- Abschnitt, der die Wetterdaten verwertet. ------------
# ------------------------------------------------------------------

wetterdaten = wetterdaten_anfrage.json()
#Benoetigte Parameter werden aus den Wetterdaten herausgefiltert:
# ... fuer die Abfrage, ob es draussen dunkel ist:
zeit = int(time.time())
sonnenaufgang = wetterdaten['sys']['sunrise']
sonnenuntergang = wetterdaten['sys']['sunset']
# ... fuer die Abfrage der Wetterart:
wetter_id = wetterdaten['weather'][0]['id']
# ... fuer die Abfrage der aktuellen Temperatur
temperatur = wetterdaten['main']['temp'] - 273.15 # Umrechnung in Celsius
# ... fuer die Abfrage, der Windgeschwindigkeit und -richtung:
windgeschwindigkeit = wetterdaten['wind']['speed'] # Meter/sec
windkmh = windgeschwindigkeit * 3.6
try:
    #Es kommt vor, dass die Wetterdaten keine Windrichtung enthalten, wenn der Wind nur sehr schwach weht.
    windrichtung = wetterdaten['wind']['deg']
except:
    #Falls keine Windrichtung angegeben wird, wird kein Wind angezeigt.
    windrichtung = -1
#Parameter einstellbar zu Testzwecken:
#temperatur = -35
#wetter_id = 800
#windkmh = 120
#windrichtung = 360

#Hier folgen ein paar Print-Ausgaben zu Testzwecken auf der Konsole:
print(windkmh)
print(windrichtung)
print(temperatur)
print(wetter_id)
print(wetterdaten['weather'][0]['description'])

# ------------------------------------------------------------------
# ---------- Abschnitt, der den LED-Streifen einrichtet. -----------
# ------------------------------------------------------------------

# LED-Streifen fuer Wettersymbole und Temperatur Konfiguration:
LED_COUNT      = 102    # Anzahl der LEDs auf dem angesteuerten Streifen.
LED_PIN        = 18     # GPIO, an dem der LED-Streifen angeschlossen ist.
LED_FREQ_HZ    = 800000 # LED Signal-Frequenz in Hertz.
LED_DMA        = 10     # DMA Kanal fuer das Ansteuerungssignal.
LED_BRIGHTNESS = 50     # Helligkeit des Streifens von 0 bis 255.
LED_INVERT     = False  # True um das Signal zu invertieren.
LED_CHANNEL    = 0      # Auf '1' stellen, bei GPIOs 13, 19, 41, 45 or 53.

#Abfragen von extremen Temperaturen. Anzeige leutet als warnung deutlich heller.
if temperatur > 35 or temperatur < -35 or windkmh > 100:
    LED_BRIGHTNESS = 255 
    
#Initialisierung des LED-Streifens:
LEDStreifen = Adafruit_NeoPixel(LED_COUNT, LED_PIN, LED_FREQ_HZ, LED_DMA, LED_INVERT, LED_BRIGHTNESS, LED_CHANNEL)
LEDStreifen.begin()

# ------------------------------------------------------------------
# ------ Abschnitt, der die Anzeige der Wettersymbole regelt. ------
# ------------------------------------------------------------------

#Farbfestlegung zur Beleuchtung der verschiedenen Symbole:
wolkenfarbe = Color(100, 100, 100)
regenfarbe = Color(0, 0, 255)
blitzfarbe = Color(150, 255, 0)
schneefarbe = Color(255, 255, 150)
nebelfarbe = Color(50, 50, 50)

#Aufteilung der LEDs zum Beleuchten der Wettersymbole:
#LED 0-3  Klarer Himmel (Sonne/Mond)
#LED 4-8  Nebel
#LED 9-13  Wolke
#LED 14,16,18,20,22,25,27,29,31,33 Regen
#LED 15,19,23,26,30 Schnee
#LED 17,21,24,28,32 Blitze

def wolkenAnzeigen():
    #Funktion zum Anzeigen der LEDs, die die Wolke beleuchten.
    LEDStreifen.setPixelColor(9, wolkenfarbe)
    LEDStreifen.setPixelColor(10, wolkenfarbe)
    LEDStreifen.setPixelColor(11, wolkenfarbe)
    LEDStreifen.setPixelColor(12, wolkenfarbe)
    LEDStreifen.setPixelColor(13, wolkenfarbe)
    
def schneeAnzeigen(anzahl):
    #Funktion zum Anzeigen der LEDs, die den Schnee beleuchten.
    if anzahl == 5:
        LEDStreifen.setPixelColor(15, schneefarbe)
        LEDStreifen.setPixelColor(19, schneefarbe)
        LEDStreifen.setPixelColor(23, schneefarbe)
        LEDStreifen.setPixelColor(26, schneefarbe)
        LEDStreifen.setPixelColor(30, schneefarbe)
        
def regenAnzeigen(anzahl):
    #Funktion zum Anzeigen der LEDs, die den Regen beleuchten.
    #Dabei kann zwischen zwei unterschiedlichen staerken unterschieden werden.
    if anzahl >= 5:
        LEDStreifen.setPixelColor(14, regenfarbe)
        LEDStreifen.setPixelColor(18, regenfarbe)
        LEDStreifen.setPixelColor(22, regenfarbe)
        LEDStreifen.setPixelColor(27, regenfarbe)
        LEDStreifen.setPixelColor(31, regenfarbe)
    if anzahl >= 10:
        LEDStreifen.setPixelColor(16, regenfarbe)
        LEDStreifen.setPixelColor(20, regenfarbe)
        LEDStreifen.setPixelColor(25, regenfarbe)
        LEDStreifen.setPixelColor(29, regenfarbe)
        LEDStreifen.setPixelColor(33, regenfarbe)
        
def blitzeAnzeigen():
    #Funktion zum Anzeigen der LEDs, die die Blitze beleuchten.
    LEDStreifen.setPixelColor(17, blitzfarbe)
    LEDStreifen.setPixelColor(21, blitzfarbe)
    LEDStreifen.setPixelColor(24, blitzfarbe)
    LEDStreifen.setPixelColor(28, blitzfarbe)
    LEDStreifen.setPixelColor(32, blitzfarbe)
    
def nebelAnzeigen():
    #Funktion zum Anzeigen der LEDs, die den Nebel beleuchten.
    LEDStreifen.setPixelColor(4, nebelfarbe)
    LEDStreifen.setPixelColor(5, nebelfarbe)
    LEDStreifen.setPixelColor(6, nebelfarbe)
    LEDStreifen.setPixelColor(7, nebelfarbe)
    LEDStreifen.setPixelColor(8, nebelfarbe)
    
def sonneAnzeigen():
    #Funktion zum Anzeigen der LEDs, die den klaren Himmel anzeigen.
    if sonnenaufgang < zeit < sonnenuntergang:
        #Am Tag leuchtet die Sonne in gelb.
        sonnenfarbe = Color(150, 255, 0)
    else:
        #Nachts soll die "Sonne" in dunkelblau beleuchtet werden.
        sonnenfarbe = Color(0, 0, 150)     
    LEDStreifen.setPixelColor(0, sonnenfarbe)
    LEDStreifen.setPixelColor(1, sonnenfarbe)
    LEDStreifen.setPixelColor(2, sonnenfarbe)
    LEDStreifen.setPixelColor(3, sonnenfarbe)
    
#Einordnung der WetterIDs in die verschiedenen Kategorien.
if wetter_id < 210:
    print("Gewitter mit Regen")
    wolkenAnzeigen()
    regenAnzeigen(10)
    blitzeAnzeigen()
elif wetter_id < 230:
    print("Gewitter ohne Regen")
    wolkenAnzeigen()
    blitzeAnzeigen()
elif wetter_id < 300:
    print("Gewitter mit Nieseln")
    wolkenAnzeigen()
    regenAnzeigen(5)
    blitzeAnzeigen()
elif wetter_id < 500:
    print("Nieseln")
    wolkenAnzeigen()
    regenAnzeigen(5)
elif wetter_id < 600:
    print("Regen")
    wolkenAnzeigen()
    regenAnzeigen(10)
elif wetter_id > 610 and wetter_id < 620 :
    print("Schneeregen")
    wolkenAnzeigen()
    schneeAnzeigen(5)
    if wetter_id == 615 or wetter_id == 616:
        regenAnzeigen(10)
    else:
        regenAnzeigen(5)
elif wetter_id < 700:
    print("Schnee")
    wolkenAnzeigen()
    schneeAnzeigen(5)
elif wetter_id < 800:
    print("Nebel")
    nebelAnzeigen()
elif wetter_id == 800:
    print("Klarer Himmel")
    sonneAnzeigen()
elif wetter_id > 800:
    print("Wolken")
    wolkenAnzeigen() 
else:
    print("Unbekanntes Wetter")

# ------------------------------------------------------------------
# ---------- Abschnitt, der die Temperaturanzeige regelt. ----------
# ------------------------------------------------------------------

farbepositiv = Color(0, 255, 0)
farbenegativ = Color(200, 50, 200)
farbenullgrad = Color(255, 255, 255)

if temperatur >= 0.5:
    #Darstellung von Temperaturen ueber 0. Bis maximal 35 Grad Celsius.
    for i in range(34, min(int(round(temperatur,0))+34, 69)):
        LEDStreifen.setPixelColor(i, farbepositiv)
elif temperatur <= -0.5:
    #Darstellung von Temperaturen unter 0. Bis mininimal -35 Grad Celsius.
    for i in range(34, min(int(round(temperatur,0)*-1)+34, 69)):
        LEDStreifen.setPixelColor(i, farbenegativ)
else:
    #Darstellung von Temperaturen um 0.
    LEDStreifen.setPixelColor(34, farbenullgrad)
        
# ------------------------------------------------------------------
# ------------- Abschnitt, der die Windanzeige regelt. -------------
# ------------------------------------------------------------------
            
#Einordnung der Windrichtung in acht Kategorien:
if windrichtung == -1:
    windrichtungsLED = 0
elif windrichtung < 157.5:
    windrichtungsLED = int(round(float(windrichtung)/45,0))+1
elif windrichtung < 337.5:
    windrichtungsLED = int(round(float(windrichtung)/45,0)*-1)+3
else:
    windrichtungsLED = 1

# Alternative, weniger kompakte Einordnung der Windrichtung in die Kategorien.
#if windrichtung >= 337.5 or windrichtung < 22.5:
#    print('Nordwind')
#    windrichtungsLED = 1
#elif windrichtung < 67.5:
#    print('Nordostwind')
#    windrichtungsLED = 2  
#elif windrichtung < 112.5:
#    print('Ostwind')
#    windrichtungsLED = 3    
#elif windrichtung < 157.5:
#   print('Suedostwind')
#   windrichtungsLED = 4    
#elif windrichtung < 202.5:
#    print('Suedwind')
#    windrichtungsLED = -1    
#elif windrichtung < 247.5:
#    print('Suedwestwind')
#    windrichtungsLED = -2    
#elif windrichtung < 292.5:
#    print('Westwind')
#    windrichtungsLED = -3    
#elif windrichtung < 337.5:
#    print('Nordwestwind')
#    windrichtungsLED = -4

# Einordnung der Windgeschwindigkeit in sieben Kategorien zur Festlegung,
# wieviele LEDs und in welcher Farbe diese angesteuert werden muessen:

#Alternative, weniger kompakte Zuordnung in die verschiedenen Windkategorien
#windfarbe = Color(220, 80, 80)
#if windkmh <= 10:
#    print('kaum Wind')
#    windLEDAnzahl = 0
#elif windkmh <= 30:
#    print('leichte Brise')
#    windLEDAnzahl = 1
#elif windkmh <= 50:
#    print('starke Brise')
#    windLEDAnzahl = 2  
#elif windkmh <= 70:
#    print('stuermischer Wind')
#    windLEDAnzahl = 3    
#elif windkmh <= 90:
#    print('Sturm')
#    windLEDAnzahl = 4   
#elif windkmh <= 111:
#    print('starker Sturm')
#    windLEDAnzahl = 4   
#    windfarbe = Color(50, 160, 30)  
#elif windkmh > 111:
#    print('Orkan')
#    windLEDAnzahl = 4   
#    windfarbe = Color(0, 70, 250)

windfarbe = Color(220, 80, 80)
#Die Windgeschwindigkeit wird heruntergerechnet auf die Anzahl, der anzusteuernden LEDs
windLEDAnzahl = int(round(windkmh/20,0))

#Bei sehr hohen Windgeschwindigkeiten (Sturm/Orkan) wird die Farbe der LEDs als Warnung veraendert.
if windLEDAnzahl == 5:
    windfarbe = Color(50, 160, 30)
    windLEDAnzahl = 4
elif windLEDAnzahl == 6:  
    windfarbe = Color(0, 70, 250)
    windLEDAnzahl = 4  
#Die Windanzeige wird nur angesteuert, wenn mehr als 10 Km/h Wind weht.
if 5 > windLEDAnzahl >= 1:
    #Ansteuerung der LEDs zur Anzeige des Windes anhand der zuvor festgelegten Parameter
    for i in range(0, windLEDAnzahl*2-1):
            LEDStreifen.setPixelColor(int(72.5+((abs(windrichtungsLED)-1)*8)-(windrichtungsLED/abs(windrichtungsLED)*3.5)+(i*windrichtungsLED/abs(windrichtungsLED))), windfarbe)
        
#   Alternative, weniger kompakte Abfragen zur Ansteuerung der gleichen LEDs:
#   if abs(windrichtungsLED) == 1:
#       for i in range(0, windLEDAnzahl*2-1):
#           LEDStreifen.setPixelColor(int(70.5-(windrichtungsLED*3.5)+(i*windrichtungsLED)), windfarbe)
#           LEDStreifen.show()
#   elif abs(windrichtungsLED) == 2:
#       for i in range(0, windLEDAnzahl*2-1):
#           LEDStreifen.setPixelColor(int(78.5-(windrichtungsLED/2*3.5)+(i*windrichtungsLED/2)), windfarbe)
#           LEDStreifen.show()
#   elif abs(windrichtungsLED) == 3:
#       for i in range(0, windLEDAnzahl*2-1):
#           LEDStreifen.setPixelColor(int(86.5-(windrichtungsLED/3*3.5)+(i*windrichtungsLED/3)), windfarbe)
#           LEDStreifen.show()
#   elif abs(windrichtungsLED) == 4:
#       for i in range(0, windLEDAnzahl*2-1):
#           LEDStreifen.setPixelColor(int(94.5-(windrichtungsLED/4*3.5)+(i*windrichtungsLED/4)), windfarbe)
#           LEDStreifen.show()

# ------------------------------------------------------------------
# ----------------- Aktivierung des LED-Streifens ------------------
# ------------------------------------------------------------------

#Markierung der derzeit ersten LED, die noch frei ist auf dem Streifen.
#LEDStreifen.setPixelColor(101, Color(0, 0, 255))

#Aktivierung des LED-Streifens mit den zuvor getaetigten Einstellungen
LEDStreifen.show()