AuroraPi

Der AuroraPi – Polarlichtvorhersage mit dem Raspberry Pi

Wäre es nicht schön, von seinem Raspberry Pi via Mail oder Twitter kontaktiert zu werden, wenn eine hohe Chance auf Polarlichter an einer beliebigen Geo-Lokalisation besteht? Das geht einfacher, als man denkt!

Voraussetzungen:

  • RasPi mit aktuellem Betriebssystem
  • Gmail-Adresse (am besten eine separate Adresse nur für den RasPi anlegen)
  • Twitter-Account

Auf http://services.swpc.noaa.gov werden kurzfristig aktualisierte Textdateien zur Verfügung gestellt, die jedermann herunterladen und nach Belieben auswerten kann. Dies erledigt natürlich der RasPi für uns.

Das Script holt sich die Polarlichtwahrscheinlichkeit der nächsten halben Stunde, abhängig von der im Script angegebenen Geo-Position. Zudem wird der für die nächste Stunde und die nächsten 4 Stunden vorhergesagte Kp-Wert ausgegeben.

Als Quelldateien dienen:

Diese Dateien wertet das Script dann aus. Übersteigt die Wahrscheinlichkeit für Polarlichter einen bestimmten Wert (der in den Variablen festgelegt werden kann), wird entweder eine email, ein Tweet oder beides abgesetzt. Mithilfe einer Log-Datei wird dafür gesorgt, dass maximal eine email und ein Tweet pro Tag abgesetzt wird (wir wollen ja keine Spammer werden…). Die beiden Dateien werden in eine Ram-Disk auf dem RasPi gespeichert, um möglichst wenig auf die SD-Karte schreiben zu müssen.

Und so funktioniert´s:

RAM-Disk anlegen

sudo nano /etc/fstab

Dort Zeile ergänzen:

RAM-Disk mit 20MB Groesse einbinden:
tmpfs   /mnt/RAMDisk    tmpfs   nodev,nosuid,size=20M   0       0

aurora.py schreiben

Das Script hierzu ist wie folgt:

sudo nano /home/pi/Scripts/Wetter/Aurora/aurora.py

Hier der Inhalt:

#!/usr/bin/python3 
# -*- coding: utf-8 -*-

################################################################
# Script errechnet die Wahrscheinlichkeit für Polarlichter
# an einem angegeben Ort innerhalb der nächsten 30 Minuten
# Ggfs. wird eine Email und ein Tweet verschickt (max. 1x am Tag)
#
# by Matthias Pfeifer
################################################################

# Module laden
import sys;
reload (sys);
sys.setdefaultencoding("utf8")
import urllib,urllib2,smtplib,os,datetime
from twython import Twython
from time import *

################# Variablen definieren ###################
# Koordinaten Ort:
ort = "Asele"
ort_longitude = 17.353615 #0 bis 360 Grad
ort_latitude = 64.1602339 #-90 bis +90 Grad
send_mail = 1   #0=keine email senden, 1=mail senden
cut_off_aurora = 10 #Cut off, ab wann eine email versendet wird (hier bei 40% Wahrscheinlichkeit)
send_twitter = 1 #0=nicht twittern, 1=twittern
cut_off_aurora_twitter = 50 #Cut off, ab wann eine email versendet wird (hier bei 40% Wahrscheinlichkeit)
polarlichtphoto = '/media/usbstick/Wetter/Aurora/Polarlichter.jpg'
datendatei = "/mnt/RAMDisk/aurora-nowcast-map.txt" #Datei für Polarlichtwahrscheinlichkeit
kp_wertedatei = "/mnt/RAMDisk/wingkp_list.txt" #Datei für Kp-Werte
logdatei = "/media/usbstick/Wetter/Aurora/aurora_status.log" # Log-Datei, wann zuletzt gemailt oder getwittert wurde
datei = []
kp_datei = []
log = []

# Email-Einstellungen:
GMAIL_USER = 'xxx@gmail.com'
GMAIL_PASS = '***********'
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587

# Twitter-Einstellungen:
CONSUMER_KEY = '**************'
CONSUMER_SECRET = '***************'
ACCESS_KEY = '******************'
ACCESS_SECRET = '*********************'
twitter = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET)

################# Funktionen ###################
# Email versenden:
# usage: send_mail('destination_email_address','subject','text')
def send_email(recipient,subject,text):
    smtpserver = smtplib.SMTP(SMTP_SERVER,SMTP_PORT)
    smtpserver.ehlo()
    smtpserver.starttls()
    smtpserver.ehlo
    smtpserver.login(GMAIL_USER,GMAIL_PASS)
    header = 'To:'+recipient+'\n'+'From: '+GMAIL_USER
    header = header+'\n'+'Subject:'+subject+'\n'
    msg = header+'\n'+text+'\n\n'
    smtpserver.sendmail(GMAIL_USER,recipient,msg)
    smtpserver.close()

################# Programmstart ########################
# Datum holen:
lt = localtime()
datum = strftime("%d.%m.%Y", lt)

# Logdatei in Liste einlesen:
f = open(logdatei,"r")
for line in f:
 log.append(line.strip())
f.close()
# Datum letzte Mail holen:
logliste = (log[0]).split("=") #Zeile am = zerlegen
datum_letzte_mail = logliste[1]
# Datum letzter Tweet holen:
logliste = (log[1]).split("=") #Zeile am = zerlegen
datum_letzter_tweet = logliste[1]

################## Polarlichtwahrscheinlichkeit#########
#Datendatei für Polarlichtwahrscheinlichkeit holen:
print("Hole aktuelle Datendatei für Polarlichtwahrscheinlichkeit von der Website http://services.swpc.noaa.gov...")
urllib.urlretrieve ("http://services.swpc.noaa.gov/text/aurora-nowcast-map.txt", datendatei)
print("Datendatei geladen.")

# Zeilenpositon der Koordinaten berechnen:
# 360 Grad in 1024 Spalten
spalte = int(float(ort_longitude)*(1024/360))

# -90 bis +90 Grad in 512 Zeilen
if ort_latitude < 0:
 zeile = int(float((90 - (-ort_latitude))*(512/180)))+17 #17 Zeilen Text in der Datei, bevor die Daten kommen
elif ort_latitude >= 0:
 zeile = int(float((90 + ort_latitude)*(512/180))+16) #17 Zeilen Text in der Datei, bevor die Daten kommen
# Datendatei in Liste einlesen:
f = open(datendatei,"r")
for line in f:
 datei.append(line)
f.close()

# Entsprechende Zeile auslesen und in Liste schreiben:
latitude = (datei[zeile]).split("   ") #Zeile an den Leerzeichen zerlegen

################### Kp-Wert holen ######################
# Datendatei holen:
print("Hole aktuelle Datendatei für Kp-Werte von der Website http://services.swpc.noaa.gov...")
resp = urllib2.urlopen('ftp://ftp.swpc.noaa.gov/pub/lists/wingkp/wingkp_list.txt')
with open(kp_wertedatei, 'wb') as f:
  f.write(resp.read())
print("Datendatei geladen.")

# Datendatei Kp-Werte in Liste einlesen:
f = open(kp_wertedatei,"r")
for line in f:
 kp_datei.append(line)
f.close()

# Letzte Zeile in String einlesen und Daten hieraus auslesen:
letzte_zeile = kp_datei[(len(kp_datei))-1]
data_from = letzte_zeile[12:14]+":"+letzte_zeile[14:16]
datum_one_hour_predicted_kp_wert = letzte_zeile[28:30]+"."+letzte_zeile[25:27]+"."+letzte_zeile[20:24]
datum_four_hour_predicted_kp_wert = letzte_zeile[57:59]+"."+letzte_zeile[54:56]+"."+letzte_zeile[49:53]
time_one_hour_predicted_kp_wert = letzte_zeile[32:34]+":"+letzte_zeile[34:36]
time_four_hour_predicted_kp_wert = letzte_zeile[61:63]+":"+letzte_zeile[63:65]
one_hour_predicted_kp_wert = letzte_zeile[41:45]
four_hour_predicted_kp_wert = letzte_zeile[70:74]

#################### Ausgabe der Ergebnisse #####################
percentage = int(latitude[spalte]) # Wahrscheinlichkeit für Polarlichte in Prozent
perc = str(percentage)
ausgabe = 'Die Wahrscheinlichkeit für Polarlichter in '+ort+' innerhalb der nächsten 30 Minuten beträgt '+perc+' Prozent.\n'
ausgabe = ausgabe+'Für den '+datum_one_hour_predicted_kp_wert+' um '+time_one_hour_predicted_kp_wert+' ist ein Kp-Wert von '+one_hour_predicted_kp_wert+' '
ausgabe = ausgabe+'vorhergesagt (1-Stunden-Prognose).\nFür den '+datum_four_hour_predicted_kp_wert+' um '+time_four_hour_predicted_kp_wert+' '
ausgabe = ausgabe+'ist ein Kp-Wert von '+four_hour_predicted_kp_wert+' vorhergesagt (4-Stunden-Prognose).\nKp-Daten von '+data_from+'.'
print(ausgabe)

# Email bei hoher Wahrscheinlichkeit senden:
#msg = ausgabe+' Bitte Fotoapparat bereit machen und Stativ nicht vergessen!'
if percentage >= cut_off_aurora:
    if send_mail == 1: 
        if str(datum_letzte_mail) != str(datum): #heute noch keine email versandt, dann los...
            send_email('empfaenger@gmail.com', \
            'Achtung Polarlichter', \
            ausgabe)
            neue_zeile_logdatei = 'letztemail='+datum+'\n'
            log[0] = neue_zeile_logdatei
            f = open(logdatei,"w")
            for item in log:
                f.write(item)
            f.close()
        else:
            print("Heute wurde schon eine Email verschickt, dass ist genug")    
    elif send_mail == 0:
        print("Wahrscheinlichkeit liegt über dem Cut-Off, Erinnerungs-EMail wird aber wunschgemäß nicht verschickt.")
    else:
        print("Bitte Email-Einstellungen im Script überprüfen.")

# Twitter-Nachricht senden:
msg="Polarlichtwahrscheinlichkeit in "+ort+" derzeit bei "+perc+" Prozent. Fotoapparat bereit machen und Stativ nicht vergessen!"
if percentage >= cut_off_aurora_twitter:
    if send_twitter == 1:
        if str(datum_letzter_tweet) != str(datum): #heute noch keinen Tweet versandt, dann los...
            photo = open(polarlichtphoto,'rb')
            twitter.update_status_with_media(media=photo, status=msg)
            neue_zeile_logdatei = 'letztertweet='+datum+'\n'
            log[1] = neue_zeile_logdatei
            f = open(logdatei,"w")
            for item in log:
                f.write(item)
            f.close()
        else:
            print("Heute wurde schon ein Tweet verschickt, dass ist genug")
    elif send_twitter == 0:
        print("Wahrscheinlichkeit liegt über dem Cut-Off, Twitter-Nachricht wird aber wunschgemäß nicht verschickt.")
    else:
        print("Bitte Twitter-Einstellungen im Script überprüfen.")

####################### Programm-Ende ###################
print("Programm vollständig abgearbeitet.")

Nun noch das Programm in die Crontab eintragen (z.B. mit Aufruf alle 30 Minuten), dann habt Ihr Euren vollautomatischen AuroraPi. Und wenn Ihr etwas mehr über Polarlichter erfahren wollt, dann lest hier weiter.

Ich freue mich auf Euer Feedback oder Verbesserungsvorschläge!

1 Antwort

  1. niwu sagt:

    Hallo

    eine geile Idee ist das.

    Doch leider bekomme ich das hier als Fehlermeldung

    root@raspi3-cam:~# python2.7 /home/pi/scripte/Wetter/Aurora/aurora.py
    Traceback (most recent call last):
    File „/home/pi/scripte/Wetter/Aurora/aurora.py“, line 92, in
    logliste = (log[0]).split(„=“) #Zeile am = zerlegen
    IndexError: list index out of range

    root@raspi3-cam:~# python3 /home/pi/scripte/Wetter/Aurora/aurora.py
    Traceback (most recent call last):
    File „/home/pi/scripte/Wetter/Aurora/aurora.py“, line 14, in
    reload (sys);
    NameError: name ‚reload‘ is not defined

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

neun + fünfzehn =

%d Bloggern gefällt das: