Da nun der Telegram-Bot erstellt wurde und der API-Key für die Kommunikation zwischen Raspberry PI vergeben wurde, können im weiteren Verlauf die fehlenden Funktionalitäten in den Programmcode eingebunden werden. 

Erinnerung zur erhofften Funktionalität der Anlage

Zum einen soll über Telegram der Anwender der Anlage eine Stromwarnung bekommen, wenn ein bestimmter, festgelegter Stromwert überschritten wurde. Dies soll simulieren, dass beispielsweise in einer realen Anlage ein mechanisches Bauteil blockiert oder überlastet und die Stromaufnahme unerwartet steigt, außerdem soll dem Anwender gezeigt werden, dass eventuell Maßnahmen zur Stromeinsparung im Hinblick auf Umweltschutz zu tätigen sind. 

Zum anderen soll die Garagenbeleuchtung, die bereits installiert wurde, nun auch über die Telegram App steuerbar sein. Man könnte sich vorstellen, dass der Anwender mit seinem Auto nach Hause kommt und einfach über Telegram seine Garagenbeleuchtung anschaltet, um die Smart-Home Thematik aufzugreifen.

Im folgenden werde ich wieder einzelne Programmfragmente einfügen und danach die jeweilige Erklärung dazu liefern.

TOKEN = '1629362245:AAFHJUf03n5YQsYKMUR6_yut6mHox0oIUhs'

Als erstes muss der vorher durch den Telegram Bot erstellte API Key, hier Token genannt deklariert werden, um eine eindeutige Kommunikation zwischen Raspberry und Telegram zu ermöglichen, denn die Stromwarnung beispielsweise soll natürlich nur auf Ihren erstellten Telegram Bot geschickt werden. Da der Zugriffstoken später noch gebraucht wird, muss er oben in der Rubrik der Konstanten deklariert werden, damit er nicht mühsam per Hand eingegeben werden muss.

MAX_CURRENT_TRESHOLD = 11 

Es wurde sich dazu entschieden einen maximalen Strom-Schwellenwert von 11 A zu wählen. Denke daran, dass Du eine RCD/LS Kombination mit einer B10 Charakteristik ausgewählt hast, um das T1-Board abzusichern und es auch freizuschalten. Diskutiere ggf., ob dieser Schwellenwert in Ordnung ist. Hier befinden sich noch einige Informationen über LS-Schalter und deren Abschaltcharakteristiken bzw. -zeiten.

MOSFET_PIN = 25 

In dem Absatz der Pin-Deklarationen wird jetzt der Steuerpin für das MOS-Modul deklariert. Aufgrund der Tatsache, dass in den aller ersten Zeilen des Codes bereits die GPIO-Bibliothek eingefügt wurde, kann aus syntaktischen Gründen der Pin einfach "25" genannt werden, weil die Steuerleitung vom MOS-Modul, an den Steckplatz 22 des Raspberry angeschlossen wird. 

Für alle Interessierte: GPIO heißt "General Purpose Input Output und beschreibt die einfachste Raspberry Schnittstelle, die wir nutzen. Sie kann als Output, also als Ausgabe oder Input, also als Eingabe verwendet werden. In unserem Anwendungsfall möchten wir ein Steuersignal auf den Gate-Anschluss des MOS-Moduls geben, den Pin "SIG", also müssen wir die Schnittstelle als Output festlegen (dazu später mehr). Diese Schnittstelle funktioniert nach einfachster binärer Vorgehensweise. Wenn Du den entsprechenden Pin als Output in Ihrem Programm freigibst, entsteht ein "1"-Signal und 3,3 V liegen an dem Pin zu Masse an. Diese Spannung reicht aus, um das MOS-Modul zu schalten. Wird ein "0"-Signal auf den Pin gegeben, dann fällt auch wieder die Steuerspannung und damit die Ansteuerung des MOS-Moduls ab. Im Datenblatt des MOS-Moduls findest Du weitere interessante Informationen über die erforderliche Spannung des Transistors und dort bekommst Du auch eine Antwort auf die Frage, weshalb eine Versorgungsspannung von 5 V beim Betrieb des MOS-Moduls ausreicht (page 3).

 An dieser Stelle fragt sich der aufmerksame Leser natürlich, wie das zusammenpassen kann. Lasse Dich nicht von dem Raspberry PI GPIO PinOut verunsichern. Dieses ist im folgenden noch einmal zu sehen.

gpio_raspberry

GPIO PinOut Raspberry PI; Quelle: raspberry.org

Du siehst: Du hast alles korrekt verdrahtet! Am Steckplatz 22, der auch im Schaltplan verzeichnet ist, befindet sich der GPIO Pin 25.

t1bot = telepot.Bot(TOKEN)

Da der Bot bereits in der Telegram App erstellt wurde, muss er jetzt auch noch in unserem Python Programm initialisiert werden. Die eingangs importierte "telepot"-Bibliothek hilft hier weiter, indem der Befehl telepot-Bot() aufgerufen werden kann, dem dann der anfangs deklarierte API-Schlüssel unseres Channels übergeben wird.

def telebotCallback(msg):
    chat_id = msg['chat']['id']
    command = msg['text']
    if(command=="/start"):
        t1bot.sendMessage(chat_id, "Nutze /register um dich für Warnmeldungen zu registrieren oder /an und /aus um die Garagenbeleuchtung zu bedienen.")
    elif(command=="/register"): 
        f = open("./users.txt", "a")  
        f.write(str(chat_id) + "\n")
        t1bot.sendMessage(chat_id, "Du hast dich für Warnmeldungen registriert.")
        print("Ein Benutzer hat sich für Warnmeldungen registriert.")
        f.close() 
    elif(command=="/an"):
        GPIO.output(MOSFET_PIN , GPIO.HIGH) #MOSFET-PIN bekommt 3.3 V HIGH-Signal
        t1bot.sendMessage(chat_id, "Die Garagenbeleuchtung wurde eingeschaltet.")
    elif(command=="/aus"):
        GPIO.output(MOSFET_PIN , GPIO.LOW) #MOSFET-PIN bekommt 0 V LOW-Signal
        t1bot.sendMessage(chat_id, "Die Garagenbeleuchtung wurde ausgeschaltet.")
    else:
        t1bot.sendMessage(chat_id, "Dieses Kommando existiert nicht. Nutze /register /an oder /aus.")

In dieser Methode geht es um die Registrierung neuer Nutzer für Warnmeldungen und die Steuerung der Gargagenbeleuchtung. Es soll nämlich nur derjenige Anwender eine Warnmeldung bekommen, der sich auch dafür angemeldet hat. Die Garagenbeleuchtung hingegen steuern kann jeder. 

Dazu muss zu Anfang im gleichen Ordner, wo auch Ihr Python Skript auf dem Raspberry gespeichert ist eine .txt-Datei angelegt werden. Beim Prototyp hieß diese Datei einfach users.txt In dieser Datei werden folglich alle Chat-IDs, also alle Nutzer, die Warnmeldungen erhalten wollen, hineingeschrieben und das Programm schickt dann im Falle einer Stromüberschreitung nur an jene registrierte Nutzer eine Telegram-Nachricht. Schreibe bitte nach der Erstellung der Datei nichts in jene hinein, sonst funktioniert die eindeutige Nachrichtenzuordnung nicht mehr! Schließe die Datei einfach wieder.

Nun zur Funktionalität: 

Wird das Kommando "/start" in die Programmzeile des Bots geschrieben, so erscheint die Bot-Antwort: "Nutze /register um dich für Warnmeldungen zu registrieren oder /an und /aus um die Garagenbeleuchtung zu bedienen."

Wird dann das Kommando "/register" eingegeben, so wird durch den Befehl open() die vorher angelegte .txt-Datei geöffnet und die aktuelle Chat-ID der Person, von der die Nachricht kam, hineingeschrieben. Das "\n" signalisiert, dass nach jeder Eingabe eine neue Zeile in der Datei beschrieben wird, denn sonst würde die Funktion write() alle Chat-IDs ohne Leerzeichen hintereinander hängen. Außerdem antwortet der Telegram Bot: "Du hast dich für Warnmeldungen registriert." In die Raspberry Konsole wird als Überprüfung "Ein Benutzer hat sich für Warnmeldungen registriert." hineingeschrieben und die .txt-Datei wird wieder geschlossen mit dem Befehl close().

Will nun jemand mit dem Kommando "/an" die Garagenbeleuchtung einschalten, so wird mit dem Befehl GPIO.output() der vorher definierte MOSFET_PIN auf GPIO.HIGH gestellt, der "SIG"-Pin des MOS-Moduls bekommt also 3,3 V Steuerspannung. An dem Steuerbefehl sieht man, dass die Output-Funktion der GPIO-Bibliothek benutzt wird, das Signal wird also ausgegeben! Der Bot antwortet mit der Statusmeldung: "Die Garagenbeleuchtung wurde eingeschaltet."

Zum Ausschalten wird "/aus" getippt und auf die gleiche Art und Weise wird der MOS-Pin mit GPIO.LOW nicht mehr angesteuert. Der Bot antwortet mit der Statusmeldung: "Die Garagenbeleuchtung wurde ausgeschaltet."

Wird ein unbekanntes Kommando eingegeben, dann antwortet der Bot mit "Dieses Kommando existiert nicht. Nutze /register /an oder /aus.".

def sendWarnIfCurrentToHigh(current):
    if(current>=MAX_CURRENT_TRESHOLD):
        try:
            f = open("./users.txt", "r")
            for line in f.readlines():
                t1bot.sendMessage(line, "Warnung: Der Stromfluss beträgt " + str(current) + " A. Der Stromfluss ist zu hoch, bitte überprüfen.")
            f.close()
        except IOError:
            print("Bisher ist kein Benutzer für Warnmeldungen registriert.") 

Nun wird die eigentliche Stromwarnung programmiert, die wie bereits beschrieben, dann an alle registrierten Nutzer geschickt wird, wenn ein Stromverbrauch von 11 A überschritten wird.

Die verwendete Methode bekommt den aktuellen Stromwert übergeben (fett in der ersten Zeile gekennzeichnet). Damit wird in der if-Bedingung der nächsten Zeile ein Vergleich mit dem Schwellenwert von 11 A getätigt. Ist der aktuelle Stromwert höher oder gleich dem Schwellenwert, wird wieder die angelegte .txt-Datei geöffnet und an alle registrierte Nutzer die Nachricht geschrieben: " Warnung: Der Stromfluss beträgt (aktueller Stromwert) A. Der Stromfluss ist zu hoch, bitte überprüfen.". Danach wird die Textdatei wieder geschlossen. 

Wenn die Textdatei nicht geöffnet werden kann oder noch kein Nutzer registriert wurde, dann erscheint die Nachricht: "Bisher ist kein Nutzer für Warnmeldungen registriert.".

def main():
    MessageLoop(t1bot, telebotCallback).run_as_thread() 
    GPIO.setmode(GPIO.BCM) 
    GPIO.setwarnings(False)
    GPIO.setup(MOSFET_PIN , GPIO.OUT, initial=GPIO.LOW) 
    GPIO.setup(LIGHT_SENSOR_PIN, GPIO.IN) 
    
    while(True):
        ticks = readLightOverTime() 
        power = round(calculatePowerFromTicks(ticks), 2) 
        current = round(calculateCurrentFromPower(power), 2) 
        powerConsumption = round(calculatePowerConsumptionOverHour(power),2) 
        requests.get("https://api.thingspeak.com/update?api_key=" + API_KEY + "&" + POWER_FIELD + "=" + str(power) + "&" + CURRENT_FIELD + "=" + str(current) +
                     "&" + POWER_CONSUMPTION_FIELD + "=" + str(powerConsumption)) 
        sendWarnIfCurrentToHigh(current) 
        print("Energiedaten an ThingSpeak geschickt!") 

if __name__=="__main__": 
    main()

Nun betrachten wir noch die Main-Methode. Dort ist alles, was erweitert werden muss fett gedruckt. In der ersten Zeile wird sichergestellt, dass der T1-Bot kontinuierlich Nachrichten vom Server abfragt und die Funktion, welche für die Registrierung der Nutzer und die Steuerung der Garagenbeleuchtung verantwortlich ist, ununterbrochen ausgeführt wird.

In der zweiten Zeile wird die GPIO-Bibliothek samt dessen Befehlen initialisiert und die Warnmeldungen, die von da ausgehen könnten auf false gesetzt.

Als nächstes wird durch die GPIO.setup()-Methode sichergestellt, dass der Initialzustand des MOSFET-Pins bei GPIO.LOW liegt also das MOS-Modul nicht angesteuert wird, nur wenn der entsprechende Befehl ausgeführt wurde.

Durch Aufruf der sendWarnIfCurrentToHigh(current)-Methode in der while(true)-Schleife der main-Methode wird sichergestellt, dass die Abfrage nach einem zu hohen Stromverbrauch kontinuierlich passiert.

Zuletzt geändert: Donnerstag, 5. August 2021, 10:47