2. November 2020 13:04 Uhr - Veröffentlicht von

Vorgeschichte

Um einen möglichst hohen Ertrag, wenig Arbeit und möglichst ökologisch Anzubauen, haben meine Mitbewohnerin im März 2020 (Hochpunkt erste Corona-Welle) das Projekt gestartet. Am Anfang hatten wir keine Ahnung welche Hardware und Software wir benötigten. Nach kurzer Recherche entschlossen wir uns in C zu programmieren, aber was sich als äußerst übertrieben herausstellte. Schnell wechselten wir auf Phyton und probierten die Ideen aus dem Internet umzusetzen. Wir bestellten uns Bausätze von kondensative Feuchtigkeitssensoren, die wir selbst verlöteten. Die Ergebnisse waren auch hier ernüchternt. Die Messungen schwankten zu extrem, um ein Grundgerüst programmieren zu können. Ca. 6 Monate später brachten neue fertig gelöhtete Sensoren und ein ACDC Wandler die Erlösung. Hier beginnt das Wichtige!

Künstliche Beleuchtung

Es ist mal wieder Winter. Kurz und knapp, wir brauchen Licht. Energiesparend und effizient muss es sein: LED! Für den Anfang ist es egal welche LED, hauptsächlich sie hat ein ausgewogenes Farbspektrum. Die Test starten, sobald sie installiert ist.

Steuerung LED

Vermutlich werde ich die Lampe über eine Website im Intranet steuern. Warum? Dann kann jeder im lokalen Netzwerk darauf zugreifen und checken, ob alles noch funktioniert. Von außen muss es ja niemand mitbekommen und wenn schon, dann kann die Person sich über einen VPN verbinden.

Erste Testphase

Momentan läuft das Script auf der Raspberry und die Feuchtigkeit wird minütlich gemessen. Ein Zähler für die Pumpzyklen soll die Pumpe vor Schäden schützen durch zu niedrigen Wasserstand.

Sensor ist mit Nagellack beschichtet worden um ein Aufquellen zu verhindern.

Das Licht wird jetzt automatisch gesteuert.

Websitensteuerung über Synology Nas

Programm Code Version 1.0

#######################################################
    #Besonderheiten
    #Über FTP Verbindung wird eine Datei auf die Pi geschrieben, die eingelesen wird
    #FTP-Datei zeigt Änderung, danach Verbindung an Server mySQL
    #Über die Funktion Verbindung() wird eine Verbindung aufgebaut, danach werden die Werte übertragen Werte_uebertragen() 
    #oder eingelesen Werte_einlesen() und dann die Verbindung getrennt
#######################################################

#######################################################
    #Bibliotheken
#######################################################

import RPi.GPIO as GPIO #GPIOs 
import Adafruit_ADS1x15 #Bodenfeuchtigkeitssensor
import time #Zeit
import sys, mysql.connector #Für Datenbank MySQL

#######################################################
    #Variablen
#######################################################

##Benötigte Einstellungen Raspberry Pi

#GPIO mode (BOARD / BCM)
GPIO.setmode(GPIO.BCM) # GPIO Nummern statt Board Nummern

#Define GPIO Pin to listen
RELAIS_1_GPIO = 27 #Relais_Pumpe_1
RELAIS_2_GPIO = 26 #Relais_Licht_1

#Modus von Pin zuweisen, Relais
GPIO.setup(RELAIS_1_GPIO, GPIO.OUT) #Pumpe_1
GPIO.setup(RELAIS_2_GPIO, GPIO.OUT) #Licht_1

##Starteinstellungen
#Pumpe am Anfang auf aus
GPIO.output(RELAIS_1_GPIO, GPIO.HIGH) # aus

#Licht am Anfang auf aus
GPIO.output(RELAIS_2_GPIO, GPIO.HIGH) # aus

adc = Adafruit_ADS1x15.ADS1115() # Create an ADS1115 ADC (16-bit) instance
GAIN = 1

###########################
    #Benutzerspezifische Variablen 
##########################

##Feuchtigkeit
Feuchtigkeit = 20600
## Wasser
#Zähler für minimalen Wasserstand
i = 0
#Limit für Wasserzähler
Limit = 40
#Pumpdauer
Pumpdauer = 20 #in s.

##Startvariable (später aus Datenbank)
#Start
Start = 0 #erster Durchlauf, dann auf 1
Fehlerschutz = 1

##Bodenfeuchtigkeit Messvariablen
#Peroide für Messung
Periode = 15 #in Minuten

#Einmaliges ausführen beim Messen
m_var = 1

##Lichtsteurung
#L_A = 8 #Licht an ab L_A Uhr
#L_E = 18 #Licht aus ab L_E Uhr
Lampe_db = 2 #am Anfang auf automatisch

##Datenbankinformationen
servername ="192.168.9.24" #Serveradresse für Hauptserver im Lokalen Netzwerk
Port ="3307"
Benutzer = "Benutzernmen" #Benutzernamen in phpmyadmin mit Zugriff auf MariaDB10
pw = "Passwort" #Das Passwort dazu
Datenbank = "Datenbank" #Name der Datenbank, auf die zugegriffen werden soll
Tabellenname = "Tabelle"

###für Suchfunktion
Tabellenname = "pi"
Suchspalte = "id"

#######################################################
    #Funktionen
#######################################################
#########
    #Messung von Bodenfeuchtigkeit
#########

def Messung():
    Ergebnis = adc.read_adc(0, gain=GAIN)
    return Ergebnis

####Zeitangabe erzeugen
def Uhrzeit():
    # aktuelle Zeit als Tupel
    lt = time.localtime()
    stunde, minute, sekunde = lt[3:6]
    Stunde_0 = f"{stunde:02d}"
    Minute_0 = f"{minute:02d}"
    Sekunde_0 = f"{sekunde:02d}"
    return stunde, minute, sekunde, Stunde_0, Minute_0

def Zeitstempel(Stunde,Minute,Sekunde):
    print(f"Uhrzeit: {Stunde:02d}:{Minute:02d}:{Sekunde:02d}")

def Status():
    Stunde, Minute, Sekunde, Stunde_0, Sekunde_0 = Uhrzeit()
    Minute1 = Minute
    time.sleep(0.5)
    Stunde, Minute, Sekunde, Stunde_0, Sekunde_0 = Uhrzeit()
    Minute2 = Minute
    if Minute1 != Minute2:
        Wert_in_MySQL(Stunde,20) #Stunde
        Wert_in_MySQL(Minute,21) #Minute


#Lampensteuerung
def Lampe():
    if Stunde >= Licht_ein and Stunde <= Licht_aus and Lampe_db == 2 or Lampe_db == 1:
        GPIO.output(RELAIS_2_GPIO, GPIO.LOW) #an
        an = "Lampe an"
        return an
    elif FTP_e == 0 or Lampe_db == 2:
        GPIO.output(RELAIS_2_GPIO, GPIO.HIGH) # aus
        aus = "Lampe aus"
        return aus

def Zyklen(Minute,Periode):
    Rest = Minute%Periode == 0 #Überprüfen, ob Rest = 0 ist, dann True, sonst False
    return Rest

def FTP_Datei_einlesen():
    try:
        datei = open("/home/pi/Nas/Licht.txt","r")      

    except:
        print("FTP Datei konnte nicht geöffnet werden")

    
    zeile01 = datei.readline() #erste Zeile einlesen
    try:
        zeile1 = int(zeile01)
    except:
        return 1
    
    return zeile1
    datei.close()
    
def FTP_Datei_schreiben():
    try:
        datei = open("/home/pi/Nas/Licht.txt","w+")      

    except:
        print("FTP Datei konnte nicht geöffnet werden. Bitte folgendes eingeben: sudo chmod 777 Licht.txt")

    datei.write("0")
    datei.close()

def Verbindung():
     # Verbindung zur Datenbank auf dem Datenbankserver erstellen
    try:
        connection = mysql.connector.connect(host= servername,
                        port= Port,
                        user= Benutzer, 
                        password= pw,
                        database = Datenbank,
                        )
        return connection
    except:
        print("Verbindung konnte nicht hergestellt werden")
        Fehlerschutz = 0
    

def Wert_in_MySQL(zu_uebertragen, id_wert):
    connection = Verbindung()
    # Execution-Objekt erzeugen
    cursor = connection.cursor()

    #Auswahl mit Zeichenkette, bei dem id = 0 ist
    temp2 = 'UPDATE pi SET wert = {} WHERE id = {}'
    sql = temp2.format(zu_uebertragen, id_wert)
    cursor.execute(sql)
    connection.commit()

    # Verbindung schliessen
    connection.close()

def Wert_aus_MySQL(id_wert):
    # Verbindung zur Datenbank auf dem Datenbankserver erstellen
    connection = Verbindung()
    # Execution-Objekt erzeugen
    cursor = connection.cursor()

    temp2 = 'SELECT * FROM pi WHERE {} = {}'
    sql = temp2.format(Suchspalte, id_wert)
    cursor.execute(sql)

    for dsatz in cursor:
        dsatz[1]
    return dsatz[1]

    # Verbindung schliessen
    connection.close()

#######################################################
    #Funktionen abrufen
#######################################################

#Hauptprogramm ist Start-Steuerung

while True:
    while Fehlerschutz == 1:
        try:
            #Uhrzeit Variablen belegen
            Stunde, Minute, Sekunde, Stunde_0, Minute_0 = Uhrzeit()
            

            #Start der Messung abrufen
            rest = Zyklen(Minute, Periode)

            #Status für Website
            Status()
            #FTP-check
            FTP_e = FTP_Datei_einlesen()

                
            if FTP_e == 1 or Start == 0:
                Lampe_db = Wert_aus_MySQL(0)
                #aktuelles Messergebnis übertagen
                Ergebnis = Messung()
                Wert_in_MySQL(Ergebnis,3)
                Wert_in_MySQL(Stunde_0,20) #Stunde
                Wert_in_MySQL(Minute_0,21) #Minute
                Limit = Wert_aus_MySQL(5)
                Feuchtigkeit_p = Wert_aus_MySQL(2)
                pumpen = Wert_aus_MySQL(1)
                i = Wert_aus_MySQL(4)
                Pumpdauer = Wert_aus_MySQL(6)
                Periode = Wert_aus_MySQL(7)
                Licht_ein = Wert_aus_MySQL(8)
                Licht_aus = Wert_aus_MySQL(9)
                if pumpen == 1:
                    #Pumpvorgang
                    GPIO.output(RELAIS_1_GPIO, GPIO.LOW) # an
                    time.sleep(5) #Pumpdauer
                    GPIO.output(RELAIS_1_GPIO, GPIO.HIGH) #aus
                    Wert_in_MySQL(0,1)
                    i += 1 #Zähler für Maximale Pumpaktionen
                    Wert_in_MySQL(i,4)
                Start = 1
                FTP_Datei_schreiben()

            #Lamensteuerung ansprechen
            Lampe()
            
            if rest == False:
                m_var = 1

            if rest == True:

                #Messergebnisse auf Variable übertragen
                m=Messung()
                Wert_in_MySQL(Stunde_0,20) #Stunde


                if m > Feuchtigkeit_p and m_var == 1:
                    Zeitstempel(Stunde,Minute,Sekunde)
                    i += 1 #Zähler für Maximale Pumpaktionen
                    print(Lampe())
                    print(m, "Bisherige Pumpzyklen", i)
                    Wert_in_MySQL(i,4)
                    #Pumpvorgang
                    GPIO.output(RELAIS_1_GPIO, GPIO.LOW) # an
                    time.sleep(Pumpdauer) #Pumpdauer
                    GPIO.output(RELAIS_1_GPIO, GPIO.HIGH) #aus
                    m_var = 2
                    
                    if i == Limit:
                        Zeitstempel(Stunde,Minute,Sekunde)
                        GPIO.output(RELAIS_1_GPIO, GPIO.HIGH) #aus
                        GPIO.output(RELAIS_2_GPIO, GPIO.HIGH) # aus
                        print("Wasserstand checken! Die maximalen Pumpzyklen von", i, "sind erreicht")
                        #break

                elif m_var == 1:
                    print(Lampe())
                    Zeitstempel(Stunde,Minute,Sekunde)
                    GPIO.output(RELAIS_1_GPIO, GPIO.HIGH) # aus ##Könnte man eigentlich weglassen
                    print(m, "Ausreichende Feuchtigkeit. Bisherige Pumpzyklen", i)
                    m_var = 2
        except:
            print("Fehler! Neustart wird versucht")
            #time.sleep(60)
            Fehlerschutz = 1 #Fehlerschutz auf 1, dass es wieder von vorne losgeht

Kategorisiert in:

Dieser Artikel wurde verfasst von Dennis

Schreibe einen Kommentar

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