# *********************************************************************** # # Wetterstation -Basismodell fuer PRIG Workshops von 2019 bis 2020 # # *********************************************************************** # Before start please setup user interface with Title, Location Hight, BMP address, etc. # (see below) # # - Hardware: # - Raspberry Pi Modell 3 or 4 (I2C, SSH and VNC Server aktive) # - Breadboard for GPIO, prototyping board or HAT # - 2 Sensors DHT22/AM2302 for measuring outdoor and indoor temperature # - 1 Sensor Adafruit BMP280 I2C or SPI Barometric Pressure & Altitude Sensor # - 1 Gas-Sensor Figaro TGS2600 # # Critical part of the system is the readout of the DHT22/AM2303 sensors (1-wire digital method) # The Adafruit method is implemented here. Critical are low temperatures that can produce sporadic errors # which can stop 'Thread 1 or 2'. Remove +VC or a restart of the script if necessary # Tutorial in German language: # https://buyzero.de/blogs/news/tutorial-dht22-dht11-und-am2302-temperatursensor-feuchtigkeitsensor-am-raspberry-pi-anschliessen-und-ansteuern # # Software: # - Operating system Raspian of 10.2019 # - Python-Programm 'Wetterstation' # # - 2 Files in program folder - tablet2.gif and evacuate.mp3 # # Configuration forthe modifikation to personal needs: # - Development on Raspi itself (create own folder) # - Development, save and tests by means of a PC PC's via VNC Viewer (Geany) # - # #_______________________________________________ from Tkinter import * from threading import Thread import time import datetime import webbrowser import RPi.GPIO as GPIO import RPi.GPIO # Import Adafruit for DHT22 Temperatur and Humidity readout import Adafruit_DHT # # Setup GPIO # Configure the Pi to use the BCM (Broadcom) pin names, rather than the pin positions RPi.GPIO.setmode(RPi.GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(17, GPIO.OUT) # LED #_______________________________________________ # setup user interface before start version = "Version 22.1.2020" panel = "Basisversion" title = "Wetterstation" location = "Spiez" hight = "655m" call = "HB9CZV" myPicture = 'tablet2.gif' # BMP280 address, 0x76 or 0x77 depending on supplier address = 0x77 # BMP280 temperature correcton (default=0) corrStationTemp = -0.0 # setup window, title and background color root = Tk() root.wm_title("Wetterstation - Raspberry Pi GUI") root.geometry('990x553+0+0') # size and position # The system color "#B40431" can be changed here, e.g. to "#585858" syscolor = "#B40431" root.config(background = syscolor) # background light grey (default): #FFFFFF # # Set up the User Interface / Frame # canvas is used for tendency canvas_width = 25 canvas_height =25 # # Start script (Anfang) def Anfang(): global pressure_nn pressure_nn = 0.0 global MidnightReset def resetGas(): L8a.configure(text= "Reset" , bg ="light grey", fg = "blue") print "\033[1;37;44m****** Reset Gas Alarm\033[0m" time.sleep (0.5) # ___________________ Left Frame _______________________ # left frame definition leftFrame = Frame(root, width=250, height = 180) leftFrame.grid(row=0, column=0, padx=15, pady=15, sticky=NW) # # label frame within the left frame leftLabel2 = Label(leftFrame, text=version, font= "Arial 11 bold ") leftLabel2.grid(row=20, column=0, padx=0, pady=0) # # GIF Picture size: 180x100 pxls # Photo, if file is not in the program folder, path must be given # ***** for photo, uncomment next lines and insert a photo in programm folder imageEx = PhotoImage(file = myPicture) Label(leftFrame, image=imageEx).grid(row=4, column=0, padx=2, pady=8) # # **** for Photo comment next 2 lines # leftLabelRevision = Label(leftFrame, text="\n\n\nPlatzhalter\n Bild", font= "Arial 12 bold") # leftLabelRevision.grid(row=4, column=0, padx=2, pady=3) # leftLabel3 = Label(leftFrame, text="Werner HB9CZV", font= "Arial 11 italic") leftLabel3.grid(row=122, column=0, padx=2, pady=2) # Revision date leftLabelRevision = Label(leftFrame, text="PRIG Basismodell", font= "Arial 15 bold", fg = syscolor) leftLabelRevision.grid(row=18, column=0, padx=2, pady=3) # CPU Temperatur leftLabelCPU = Label(leftFrame, text="CPU Temperatur", font= "Arial 11 bold ") leftLabelCPU.grid(row=21, column=0, padx=0, pady=0) # # # _______________ Slider Frame _____________________ # slider frame within the left frame sliderFrame = Frame(leftFrame) sliderFrame.grid(row=8, column=0, padx=3, pady=3, sticky=W) # # Outdoor sensor DHT22 scanning interval Slider1 = Scale(sliderFrame, from_=2, to=30, resolution=2, bd =4,fg= "white",bg = syscolor, label = "Terrasse (Minuten)",orient=HORIZONTAL, length=160, font= "Arial 10 bold") Slider1.grid(row=13, column=0, padx=5, pady=0) Slider1.set(8) # # Indoor sensor DHT33 scanning interval Slider2 = Scale(leftFrame, from_=2, to=30, resolution= 2, bd =4,fg= "white",bg = syscolor, label = "Wohnung",orient=HORIZONTAL, length=160 ,font= "Arial 10 bold") Slider2.grid(row=10, column=0, padx=1, pady=2) Slider2.set(8) # # Short time scanning interval (LED blinker, alarm, ...) Slider3 = Scale(leftFrame, from_=1, to=10, resolution=1, bd =4,fg= "white", bg = "blue", label = "Kalibrierung Luft",orient=HORIZONTAL, length=160, font= "Arial 10 bold") Slider3.grid(row=16, column=0, padx=1, pady=2) Slider3.set(2) # # Pressure/Temperatur BMP280 sensor scanning interval Slider4 = Scale(leftFrame, from_=2, to=30, resolution=2, bd =4,fg= "white" ,bg = "green" , label = "Druck/Temperatur",orient=HORIZONTAL, length=160, font= "Arial 10 bold") Slider4.grid(row=14, column=0, padx=1, pady=2) Slider4.set(12) # # ___________________ RIght Frame ____________________ # # right frame definition rightFrame = Frame(root, width=600, height = 380) rightFrame.grid(row=0, column=1, padx=1, pady=15, sticky=NW) # left upper corner # # label frame within the right frame labelFrame = Frame(rightFrame) labelFrame.grid(row=0, column=0, padx=3, pady=1, sticky=W) # Title of project L1 = Label(labelFrame,text= title, font= "Arial 36 bold" ,relief ="raised", bd =0,fg = syscolor , padx ="20",pady=1) L1.grid(column=0, row=0,sticky=E) # row 0 L1 = Label(labelFrame,text= call, font= "Arial 16 bold" ,fg = syscolor , padx ="6",pady=1) L1.grid(column=3, row=0,sticky=W) # row 0 L1a = Label(labelFrame,text= location, font= "Arial 16 bold" ,fg = syscolor , padx ="16",pady=1) L1a.grid(column=1, row=0,sticky=E) # row 0 L1b = Label(labelFrame,text=hight, font= "Arial 16 bold" ,fg = syscolor , padx ="16",pady=1) L1b.grid(column=2, row=0,sticky=W) # # row 1 Date and Time L2 = Label(labelFrame,text="Datum", font= "Arial 16 bold" ,fg = "grey",pady=5, padx ="20") L2.grid(column=0, row=1,sticky=E) # row 1 L2a = Label(labelFrame,text="Zeit", font= "Arial 18 bold" ,fg = "grey",pady=5, padx ="0") L2a.grid(column=1, row=1, sticky=NW) # row 1 L3c = Label(labelFrame,text="min / max", font= "Arial 12 bold" ,fg = "grey") L3c.grid(column=2, row=1, sticky=NW, padx ="15") # row 1 L3d = Label(labelFrame,text="Tendenz", font= "Arial 12 bold" ,fg = "grey") L3d.grid(column=3, row=1, sticky=NW, padx ="15") # L3h = Label(labelFrame,text="History", font= "Arial 12 bold" ,fg = "grey") L3h.grid(column=4, row=1, sticky=NW, padx ="15") # # row 3 Outdoor Temperature L3a = Label(labelFrame,text=" ", font= "Arial 20 bold" ,fg = syscolor, bd =4, padx ="1") L3a.grid(column=1, row=3, sticky=NW) # L3 = Label(labelFrame,text="Temperatur Terrasse", font= "Arial 20 bold" ,fg = syscolor, padx ="1") L3.grid(column=0, row=3, sticky=W) # L3b = Label(labelFrame,text=" wait ", font= "Arial 10 bold" ,fg = syscolor, padx ="20") L3b.grid(column=2, row=3, sticky=W) # # row 4 Humidity L4 = Label(labelFrame,text="Luftfeuchtigkeit", font= "Arial 14 bold" ,fg = "dark blue", padx ="25") L4.grid(column=0, row=4, sticky=NW) # row 4 L4a = Label(labelFrame,text=" ", font= "Arial 14 bold" ,fg = "dark blue", padx ="1") L4a.grid(column=1, row=4, sticky=W) # # row 6 Indoor Temperature L5 = Label(labelFrame,text="Temperatur Wohnung", font= "Arial 20 bold" ,fg = syscolor, padx ="1") L5.grid(column=0, row=6, sticky=NW) # row 6 L5a = Label(labelFrame,text=" ", font= "Arial 20 bold" ,fg = syscolor,pady=0, padx ="1" ) L5a.grid(column=1, row=6, sticky=NW) # row 6 L3c = Label(labelFrame,text=" wait ", font= "Arial 10 bold" ,fg = syscolor, padx ="20") L3c.grid(column=2, row=6, sticky=W) # row 12 L6 = Label(labelFrame,text="Luftfeuchtigkeit", font= "Arial 14 bold" ,fg = "dark blue", padx ="25") L6.grid(column=0, row=12, sticky=NW) # row 12 L6a = Label(labelFrame,text=" ", font= "Arial 14 bold" ,fg = "dark blue",padx ="1") L6a.grid(column=1, row=12, sticky=W) # # row 13 L7d = Label(labelFrame,text="Temperatur Station", font= "Arial 20 bold" ,fg = syscolor,pady=0, padx ="0") L7d.grid(column=0, row=13, sticky=W) # L7e = Label(labelFrame,text=" ", font= "Arial 20 bold" ,fg = syscolor,pady=0, padx ="0") L7e.grid(column=1, row=13, sticky=W) # # row 15 Pressure in hPa L7 = Label(labelFrame,text="Luftdruck in hPa (QFF)", font= "Arial 20 bold" ,fg = "dark green", padx ="1", pady=10) L7.grid(column=0, row=15, sticky=W) # # row 15 L7a = Label(labelFrame,text="", font= "Arial 20 bold" ,fg = "dark green",pady=0, padx ="0") L7a.grid(column=1, row=15, sticky=W) # L7f = Label(labelFrame,text=" wait ", font= "Arial 10 bold" ,fg = "dark green", padx ="20", pady ="0") L7f.grid(column=2, row=15, sticky=W) # # row 16 Absolute Presseure L7b = Label(labelFrame,text="Abs. Luftdruck (QFE-655m) in hPa", font= "Arial 12 bold" ,fg = "dark green",pady=0, padx ="0") L7b.grid(column=0, row=16, sticky=W) # L7c = Label(labelFrame,text=" ", font= "Arial 12 bold" ,fg = "dark green",pady=0, padx ="0") L7c.grid(column=1, row=16, sticky=W) # L7g = Label(labelFrame,text="Tendenz", font= "Arial 12 bold" ,fg = "dark green",pady=0, padx ="0") L7g.grid(column=2, row=16) # # row 18 L8 = Label(labelFrame,text= "Frischluft", font= "Arial 20 bold" ,fg = "blue", padx ="5") L8.grid(column=0, row=18, sticky=W, pady=4) # L8a = Button(labelFrame, text="Qualit.", fg="blue",bg="#D8D8D8",bd =4, width=6, command= resetGas, font= "Arial 12 bold") L8a.grid(row=18, column=3, padx=1, pady=1, sticky=W) # L8b = Label(labelFrame,text="Calibration", font= "Arial 12 bold" ,fg = "grey",pady=2, padx ="1" ) L8b.grid(column=2, row=18) # L8c = Label(labelFrame,text="Level", font= "Arial 20 bold" ,fg = "blue",pady=2, padx ="5" ) L8c.grid(column=1, row=18, sticky=W) # # # ________________________ Start Demo _______________________________ # Memo - Write Entry field to display # demoFrame = Frame(rightFrame) demoFrame.grid(row=18, column=0, padx=10, pady=1, sticky=W) # L10 = Label(demoFrame,text=" noch kein Memo eingegeben ", font= "Arial 13 bold" ,fg = "grey", padx ="1") L10.grid(column=1, row=18, sticky=W, pady=8) # # Entry field E1 = Entry(demoFrame, width=22, relief = "sunken",bd =2, fg = syscolor, bg = "light grey", font= "Arial 12 bold") E1.grid(row=18, column=0, padx=0, pady=6, sticky=W) # Preset: E1.insert(END, "Mein Memo") # def memo(): print(E1.get()) # Display entry text in ONE step L10.configure(text="Memo: " + E1.get(), fg =syscolor) # Change text of 'Demo' button if B1["text"] == "Memo" : B1["text"] = "Done" else: B1["text" ] = "Neues Memo" # Read and print the text field button1_text = B1["text"] print ("Button is switched " + button1_text) # Print CSV File at click of the buttom Clear csv File # ***************************************************** def printCSV(): """ Plot csv file - 20 rows """ # Tutorial about csv files: # https://www.geeksforgeeks.org/working-csv-files-python/ # importing csv module import csv # csv file name filename = "temp.csv" # initializing the titles and rows list fields = [] rows = [] # reading csv file with open(filename, 'r') as csvfile: # creating a csv reader object csvreader = csv.reader(csvfile) # extracting field names through first row fields = csvreader.next() # extracting each data row one by one for row in csvreader: rows.append(row) # get total number of rows print "\nNumber of rows: %d"%(csvreader.line_num - 1)," - max. 20 rows displayed:" # printing the field names print('\n Field Name:') print('' + ', '.join(field for field in fields)) # printing first 20 rows, line space = \n # print ('10 Rows showned:') for row in rows[:20]: # parsing each column of a row for col in row: print("%10s"%col), print('\n') # Clear CSV File at click of the button and at midnight # ***************************************************** def clearCSV(): """Reset csv file and rewrite field names for temp.csv""" import csv book_list = () # Clear content of temp.csv file without deleting the file weatherData = open("temp.csv", "w") weatherData.truncate() for i in book_list: weatherData.write("{},{},{},{}".format(i[0],i[1],i[2],i[3])) print "Mainloop: Clear content of temp.csv file" # Definition of time format to be written to the other csv files data = ["Recorded Time","Outdoor T","Outdoor H","Indoor T","Indoor H", "Pressure","BMP280 T",1 ] with open("temp.csv", "a")as output: writer = csv.writer(output, delimiter=",") writer.writerow(data) print "Mainloop: Header line written to : ", data # Clear all other csv files csvFiles = ["tempCPU.csv", "outdoor.csv", "home.csv", "tempPressure.csv","tempTempBMP280.csv", "tempGas.csv"] for file in csvFiles: weatherData = open((file), "w") weatherData.truncate() print "Mainloop: Cleared files: ", (file) weatherData.close() # Clear Fails File at click of the buttom # *************************************** def clearFails(): """Reset csv file Fails""" import csv print "Mainloop: Clear Failure files" # Clear the two failure files failureFiles = ["failureIN.csv", "failureOUT.csv"] for file in failureFiles: failureFiles = open((file), "w") failureFiles.truncate() print "Mainloop: Cleared failureFiles: ", (file) failureFiles.close() # Plot CPU Temperature from the Raspberry Pi # ***************************************************** def PlotCPUTemp(): """Plot CPU Temperature""" print "Mainloop: Start Plot CPU Temperature" # Load data from csv file # https://blog.mafr.de/2012/03/11/time-series-data-with-matplotlib/ import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates import csv # Datum und Uhrzeit # http://www.gtkdb.de/index_31_2492.html day, TemperatureCPU = np.loadtxt("tempCPU.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # Options ftm: g=green at the begin, o= dots, D= diamond at the end of line plt.figure(num='CPU Iemperatur - Wetterstation - Raspberry Pi GUI') plt.plot_date(x=day, y=TemperatureCPU, fmt="r", linewidth = 1.0, markersize=0.3) # options plt.title("CPU Temperatur" ) plt.xlabel("(01) Tag des laufenden Monats - Stunde (:Minute)") plt.ylabel("Temperatur in *Celsius") plt.grid(True) # turn the x-axis text plt.gcf().autofmt_xdate() # rotates and right aligns the x labels, and moves the bottom of the # axes up to make room for them plt.plot(day, TemperatureCPU, label="CPU Raspberry Pi \nausgelesene Temperatur\nNormal ca. 50* Celsius") plt.legend(loc='best') # plot plt.show() plt.close() csvFile.close() # Plot Indoor Temperature and Humidity in one plot # ***************************************************** def PlotIndoor(): """ Plot Temperature and Humidit """ print "Mainloop: Start Plot Indoor" # Load data from csv file # https://blog.mafr.de/2012/03/11/time-series-data-with-matplotlib/ import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates import csv # Datum und Uhrzeit: http://www.gtkdb.de/index_31_2492.html day, temperature, humidity = np.loadtxt("home.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # Plot in new window 'Innen ...' plt.figure(num='Innen - Wetterstation - Raspberry Pi GUI') plt.subplot(211) plt.plot_date(day, temperature,'ro--', linewidth=2, markersize=1) plt.title('Innentemperatur') plt.grid(True) plt.ylabel("Temperatur in Grad C") # Turn scale of the axis plt.gcf().autofmt_xdate() plt.subplot(212) plt.plot_date(day, humidity,'bo--', linewidth=2, markersize=2, label="Luftfeuchtigkeit") plt.title(' ') plt.grid(True) plt.ylabel("Luftfeuchtigkrit in %") plt.xlabel("(01) Tag des laufenden Monats - Stunde (:Minute)") plt.legend(loc='best') # Turn scale of the axis plt.gcf().autofmt_xdate() plt.show() csvFile.close() # Plot Outdoor Temperature and Humidity in one plot # ***************************************************** def PlotOutdoor(): """ Plot Temperature and Humidit """ print "Mainloop: Start Plot Outdoor" # Load data from csv file # https://blog.mafr.de/2012/03/11/time-series-data-with-matplotlib/ import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates import csv # Date and time # http://www.gtkdb.de/index_31_2492.html day, temperature, humidity = np.loadtxt("outdoor.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # converters={ 0: mdates.strpdate2num('%H-%M')}) # print day, temperature, humidity # Definition of the plot plt.figure(num='Aussen - Wetterstation - Raspberry Pi GUI') plt.subplot(211) plt.plot_date(day, temperature,'ro--', linewidth=2, markersize=1) plt.title('Aussentemperatur') plt.grid(True) plt.ylabel("Temperatur in Grad C") plt.subplot(212) plt.plot_date(day, humidity,'bo--', linewidth=2, markersize=2) plt.title(' ') plt.grid(True) plt.ylabel("Luftfeuchtigkrit in %") plt.xlabel("(01) Tag des laufenden Monats - Stunde (:Minute)") plt.gcf().autofmt_xdate() plt.show() csvFile.close() # Plot PlotAirQuality in one plot # ***************************************************** def PlotAirQuality(): """Plot Air Quality""" print "Mainloop: ", "\033[1;37;42mPlot Air Quality\033[0m" # Load data from csv file # https://blog.mafr.de/2012/03/11/time-series-data-with-matplotlib/ import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates import csv # Datum und Uhrzeit # http://www.gtkdb.de/index_31_2492.html day, quality = np.loadtxt("tempGas.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # Options ftm: g=green at the begin, o= dots, D= diamond at the end of line plt.figure(num='Luftqualitaet - Wetterstation - Raspberry Pi GUI') plt.plot_date(x=day, y=quality, fmt="b--", linewidth = 0.5) # options plt.title("Luftqualitaet in Spiez " ) plt.xlabel("(01) Tag des laufenden Monats - Stunde (:Minute)") plt.ylabel("Luftqualitaets-Index") plt.grid(True) # turn plt.gcf().autofmt_xdate() # rotates and right aligns the x labels, and moves the bottom of the # axes up to make room for them plt.plot(day, quality, label="Index 1 (best) bis 15 \nSpiezer Luft = 2 \nKalibrierung 2 oder 3\nGase (>5): Methan (CH4)\nCO, Isobutan \nEthanol, Hydrogen") plt.legend(loc='best') plt.show() plt.close() csvFile.close() # Plot Pressure in one plot # ***************************************************** def PlotPressure(): """Plot Air pressure and time in hours and minutes""" print "Mainloop: ", "\033[1;37;42mPlot Air Pressure\033[0m" # Load data from csv file # https://blog.mafr.de/2012/03/11/time-series-data-with-matplotlib/ import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates import csv # Datum und Uhrzeit # http://www.gtkdb.de/index_31_2492.html day, pressure = np.loadtxt("tempPressure.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # Options ftm: g=green at the begin, o= dots, D= diamond at the end of line plt.figure(num='Luftdruck - Wetterstation - Raspberry Pi GUI') plt.plot_date(x=day, y=pressure, fmt="g--", linewidth = 2.5) # options plt.title("Luftdruck in Spiez - Verlauf heute" ) plt.xlabel("(01) Tag des laufenden Monats - Stunde (:Minute)") plt.ylabel("Luftdruck NN hPa") plt.grid(True) # turn plt.gcf().autofmt_xdate() # rotates and right aligns the x labels, and moves the bottom of the # axes up to make room for them plt.plot(day, pressure, label="Stationshoehe = 650m \nSensor = BMP280 (+/- 1 hPa)\nmax. 24h-Aufzeichnung\nRuecksetzung um Mitternacht\nClose Alt/F4") plt.legend(loc='best') plt.show() plt.close() csvFile.close() def PlotTemperatur(): """ Temperature comparison """ print "Mainloop: ", "\033[1;37;41m* Plot 2 All Temperature\033[0m" # https://www.programiz.com/python-programming/reading-csv-files # Load data from csv file # https://blog.mafr.de/2012/03/11/time-series-data-with-matplotlib/ import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates import csv # Get temperature from sensor BMP280 day, temperature = np.loadtxt("tempTempBMP280.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # Get temperature from sensor DHT22 indoor dayDHT22, temperatureDHT22, humidityDHT22 = np.loadtxt("home.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # Get temperature from sensor DHT22 outdoor dayDHT22out, temperatureDHT22out, humidityDHT22out = np.loadtxt("outdoor.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # Options ftm: g=green at the begin, o= dots, D= diamond at the end of line plt.figure(num='Temperatur - Wetterstation - Raspberry Pi GUI') plt.plot(day, temperature, label="Sensor BMP280 indoor an Station") plt.plot(dayDHT22, temperatureDHT22, label="Sensor DHT22 indoor") plt.plot(dayDHT22out, temperatureDHT22out, label="Sensor DHT22 outdoor") plt.legend(loc='best') plt.title('Temperaturvergleich innen/aussen') plt.gcf().autofmt_xdate() plt.plot_date(x=day, y=temperature, fmt="r--", linewidth = 0.1) plt.plot_date(x=dayDHT22, y=temperatureDHT22, fmt="r--", linewidth = 0.1) plt.plot_date(x=dayDHT22out, y=temperatureDHT22out, fmt="g--", linewidth = 1.5) plt.xlabel("(01) Tag des laufenden Monats - Stunde (:Minute)") plt.ylabel("Temperatur in Grad C") plt.grid(True) plt.show() csvFile.close() # marker_style = dict(color='cornflowerblue', linestyle=':', marker='o', # markersize=55, markerfacecoloralt='ted') def PlotFailure(): """ Abnormal measurements will be stored and plotted """ print "Mainloop: ", "\033[1;37;41m* Plot Temperature Out of Tolerance\033[0m" # https://www.programiz.com/python-programming/reading-csv-files # Load data from csv file # https://blog.mafr.de/2012/03/11/time-series-data-with-matplotlib/ import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates import csv # Get temperature from sensor DHT22 indoor dayDHT22, temperatureDHT22, humidityDHT22 = np.loadtxt("failureIN.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # Get temperature from sensor DHT22 outdoor dayDHT22out, temperatureDHT22out, humidityDHT22out = np.loadtxt("failureOUT.csv", unpack=True, converters={0: mdates.strpdate2num('%d-%H-%M')}) # Options ftm: g=green at the begin, o= dots, D= diamond at the end of line plt.figure(num='Temperatur - Wetterstation - Raspberry Pi GUI') plt.plot(dayDHT22, temperatureDHT22, label="Sensor DHT22 indoor, nur Temperaturanzeige") plt.plot(dayDHT22out, temperatureDHT22out, label="Sensor DHT22 outdoor, nur Temperaturanzeige. \nKann auch Fehlmessung der Luftfeuchtigkeit sein") plt.legend(loc='best') plt.title('Fehlmessungen T&F (ausserhalb Toleranz)') plt.gcf().autofmt_xdate() plt.plot_date(x=dayDHT22, y=temperatureDHT22, fmt="rD") plt.plot_date(x=dayDHT22out, y=temperatureDHT22out, fmt="go") plt.xlabel("(01) Tag des laufenden Monats - Stunde (:Minute)") plt.ylabel("Temperatur in Grad C") plt.grid(True) plt.show() csvFile.close() # marker_style = dict(color='cornflowerblue', linestyle=':', marker='o', # markersize=55, markerfacecoloralt='ted') # ________________________End Demo _______________________________ # def OpenWebUhr(): url6 = "http://webuhr.de" webbrowser.open_new(url6) print "Website Web Uhr opened" # def OpenBio(): # url8 = 'http://meteonews.ch/de/Biowetter/G7287204/Spiez' url8 = 'https://ch.wetter.com/schweiz/spiez/CH0CH3746.html' webbrowser.open_new(url8) print "Website Forecast opened" def OpenMeteoCH(): # url9 = 'https://www.meteoschweiz.admin.ch/home/messwerte.html?param=messwerte-lufttemperatur-10min' url9 = 'https://www.meteoschweiz.admin.ch/home/messwerte.html?param=messwerte-lufttemperatur-10min' webbrowser.open_new(url9) print "Website Meteo CH opened" def OpenSwissPOP(): # url10 = 'https://radiosonline.ch/' url10 = 'https://radiosonline.ch/' webbrowser.open_new(url10) print "Website 'Internet Radio' opened" def OpenSRFmeteo(): # url11 = 'https://www.srf.ch/meteo/radar?type=1h' url11 = 'https://www.srf.ch/meteo/radar?type=1h' webbrowser.open_new(url11) print "Website STF Meteo opened" # # Toggle button text from ON to OFF (white button) def midnight(): if B10["text"] == "Reset Ein" : MidnightReset = 0 B10["text"] = "Reset Aus" print "Mainloop: Midnight Reset is swiched OFF" else: B10["text" ] = "Reset Ein" print "Mainloop: Midnight Reset is swiched ON" MidnightReset = 1 # Subframe to arrange several buttons in a row buttonFrame = Frame(rightFrame) buttonFrame.grid(row=20, column=0, padx=5, pady=3, sticky=W) # B1 = Button(buttonFrame, text="Memo", bg=syscolor,bd =4, fg="white" ,width=8, command=memo, font= "Arial 10 bold") B1.grid(row=15, column=0, padx=2, pady=3, sticky=W) # B2 = Button(buttonFrame, text="Web Uhr", bg=syscolor, fg="white", bd =4, width=8, command=OpenWebUhr, font= "Arial 10 bold") B2.grid(row=15, column=1, padx=2, pady=3, sticky=W) # B3 = Button(buttonFrame, text="Show csv", bg="#FFFF00",bd =4, width=8, command=printCSV, font= "Arial 10 bold") B3.grid(row=15, column=4, padx=2, pady=3, sticky=W) B3a = Button(buttonFrame, text="CPU Temp", bg=syscolor, fg="white", bd =4, width=8, command=(PlotCPUTemp), font= "Arial 10 bold") B3a.grid(row=15, column=2, padx=2, pady=3, sticky=W) # B4 = Button(buttonFrame, text="Prognose", fg="white",bd =4, bg="green", width=8, command=(OpenBio), font= "Arial 10 bold") B4.grid(row=16, column=0, padx=2, pady=3, sticky=W) # B5 = Button(buttonFrame, text="Meteo CH", fg="white",bg="green",bd =4, width=8, command=(OpenMeteoCH), font= "Arial 10 bold") B5.grid(row=16, column=1, padx=2, pady=3, sticky=W) # B6 = Button(buttonFrame, text="Radio", fg="white",bg="green",bd =4, width=8, command=(OpenSwissPOP), font= "Arial 10 bold") B6.grid(row=16, column=2, padx=2, pady=3, sticky=W) # B7 = Button(buttonFrame, text="SRF Meteo", fg="white", bg="green",bd =4, width=8, command=(OpenSRFmeteo), font= "Arial 10 bold") B7.grid(row=16, column=3, padx=2, pady=3, sticky=W) # B8 = Button(buttonFrame, text="Reserve 5", fg="black", bg="light grey",bd =4, width=8, command=(), font= "Arial 10 bold") B8.grid(row=16, column=4, padx=2, pady=3, sticky=W) # B9 = Button(buttonFrame, text="Clear csv", bg="#FFFF00",fg = "red", width=8,bd =4, command = clearCSV, font= "Arial 10 bold") B9.grid(row=15, column=5, padx=2, pady=3, sticky=W) B9a = Button(buttonFrame, text="Show Fails", bg="#FFFF00",fg = "black", width=8,bd =4, command = PlotFailure, font= "Arial 10 bold") B9a.grid(row=15, column=6, padx=2, pady=3, sticky=W) B9b = Button(buttonFrame, text="Clear Fails", bg="#FFFF00",fg = "red", width=8,bd =4, command = clearFails, font= "Arial 10 bold") B9b.grid(row=15, column=7, padx=2, pady=3, sticky=W) # B10 = Button(buttonFrame, text= "24h-Reset", bg=syscolor ,fg="white", width=8,bd =4, command= midnight, font= "Arial 10 bold") B10.grid(row=15, column=3, padx=2, pady=3, sticky=W) B11 = Button(buttonFrame, text="Reserve 6" , bg="light grey", width=8,bd =4,fg="black" , command = (), font= "Arial 10 bold") B11.grid(row=16, column=5, padx=2, pady=3, sticky=W) B12 = Button(buttonFrame, text="Reserve 7" , bg="light grey", width=8,bd =4,fg="black" , command = (), font= "Arial 10 bold") B12.grid(row=16, column=6, padx=2, pady=3, sticky=W) B13 = Button(buttonFrame, text="Reserve 8" , bg="light grey", width=8,bd =4,fg="black" , command = (), font= "Arial 10 bold") B13.grid(row=16, column=7, padx=2, pady=3, sticky=W) # ------------------------------------------------- B6h = Button(labelFrame,text="Aussen", fg="white",bg=syscolor,bd =4, width=4, command=PlotOutdoor, font= "Arial 10 bold") B6h.grid(row=3, column=4, padx=2, pady=3, sticky=W) B7h = Button(labelFrame,text="Innen", fg="white",bg=syscolor,bd =4, width=4, command=PlotIndoor, font= "Arial 10 bold") B7h.grid(row=6, column=4, padx=2, pady=3, sticky=W) B13h = Button(labelFrame,text="Temp.", fg="white",bg=syscolor,bd =4, width=4, command=PlotTemperatur, font= "Arial 10 bold") B13h.grid(row=13, column=4, padx=2, pady=3, sticky=W) B17h = Button(labelFrame,text="Druck", fg="white",bg="green",bd =4, width=4, command=PlotPressure, font= "Arial 10 bold") B17h.grid(row=15, column=4, padx=2, pady=3, sticky=W) B18h = Button(labelFrame,text="Luft", fg="white",bg="blue",bd =4, width=4, command=PlotAirQuality, font= "Arial 10 bold") B18h.grid(row=18, column=4, padx=2, pady=3, sticky=W) # # canvas_Color = syscolor # canvasTempStable = Canvas(buttonFrame, width=canvas_width, height=canvas_height) # canvasTempStable.grid(column=5, row=15, pady=0) # points = [0,0,canvas_width,canvas_height/2, 0, canvas_height] # canvasTempStable.create_polygon(points, outline="grey", # fill='yellow', width=3) # # # # Sensor 4 (BMP280) - Luftdruck und Temperatatur (BMP280) # ****************************************************** # Refer to: http://www.netzmafia.de/skripten/hardware/RasPi/Projekt-BMP280/index.html # Datenblatt: https://cdn-shop.adafruit.com/datasheets/BST-BMP280-DS001-11.pdf # realiced with I2C-Interface # import smbus # import time # import time only if stand-alone # standart delay for 5 Minute interval delay4 = 120 minPressure= 0000.0 maxPressure= 0000.0 pressure2 = 0000.0 # # ________________________ Pressure (4) ___________________________ # ******************************************** # Sensor 4 (BHP280) - Pressure and Temperature # ******************************************** # # 1 Definition local variables def task4 (name, delay, repeat): """ Sensor 4 (BHP280) - Pressure and Temperature """ minPress= 0000.0 maxPress= 0000.0 time.sleep(20) pressure2 = 0000.0 reset = 1 tolChange =0.25 # 2 Preset minimum delay between 2 readouts delay4 = 120 # Read slider4 (delay 4) delay4 = Slider4.get() pressureStore = 0000 print ("Thread for: " + name + " started") print "\033[1;37;42m**** Air Pressure\033[0m" # 3 Count down repeat until 0 while repeat > 0: # 4 Read I2C bus and calculation # Number of I2C bus BUS = 1 # BMP280 address, 0x76 or 0x77 BMP280ADDR = address # altitude 650m for Spiez ALTITUDE = 655 # Get I2C bus bus = smbus.SMBus(BUS) # Temperature calibration coeff. array T = [0, 0, 0]; # Pressure calibration coeff. array P = [0, 0, 0, 0, 0, 0, 0, 0, 0]; # Read calibration data from 0x88, 24 bytes data = bus.read_i2c_block_data(BMP280ADDR, 0x88, 24) # Temp coefficents T[0] = data[1] * 256 + data[0] T[1] = data[3] * 256 + data[2] if T[1] > 32767: T[1] -= 65536 T[2] = data[5] * 256 + data[4] if T[2] > 32767: T[2] -= 65536 # Pressure coefficents P[0] = data[7] * 256 + data[6]; for i in range (0, 8): P[i+1] = data[2*i+9]*256 + data[2*i+8]; if P[i+1] > 32767: P[i+1] -= 65536 # select control measurement register, 0xF4 # 0x27: pressure/temperature oversampling rate = 1, normal mode bus.write_byte_data(BMP280ADDR, 0xF4, 0x27) # select configuration register, 0xF5 # 0xA0: standby time = 1000 ms bus.write_byte_data(BMP280ADDR, 0xF5, 0xA0) time.sleep(1.0) # read data from 0xF7, 8 bytes data = bus.read_i2c_block_data(BMP280ADDR, 0xF7, 8) # convert pressure and temperature data to 19 bits adc_p = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4) adc_t = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4) # convert pressure and temperature data to 19 bits adc_p = (data[0] << 12) | (data[1] << 4) | (data[2] >> 4) adc_t = (data[3] << 12) | (data[4] << 4) | (data[5] >> 4) # temperature offset calculations temp1 = ((adc_t)/16384.0 - (T[0])/1024.0)*(T[1]); temp3 = (adc_t)/131072.0 - (T[0])/8192.0; temp2 = temp3*temp3*(T[2]); temperature_4 = (temp1 + temp2)/5120.0 temperature_4 = temperature_4 + corrStationTemp # pressure offset calculations press1 = (temp1 + temp2)/2.0 - 64000.0 press2 = press1*press1*(P[5])/32768.0 press2 = press2 + press1*(P[4])*2.0 press2 = press2/4.0 + (P[3])*65536.0 press1 = ((P[2])*press1*press1/524288.0 + (P[1])*press1)/524288.0 press1 = (1.0 + press1/32768.0)*(P[0]) press3 = 1048576.0 - (adc_p) if press1 != 0: press3 = (press3 - press2/4096.0)*6250.0/press1 press1 = press3*press3*(P[8])/2147483648.0 press2 = press3*(P[7])/32768.0 pressure = (press3 + (press1 + press2 + (P[6]))/16.0)/100 else: pressure = 0 # pressure relative to sea level pressure_nn = pressure/pow(1 - ALTITUDE/44330.0, 5.255) # 5 write data to display and terminal L7c.configure(text= "%.1f" %pressure + " ") L7a.configure(text= "%.1f" %pressure_nn + " ") L7e.configure(text= "%.1f" %temperature_4 + " ") time.sleep(1) timeMark = time.strftime("%H:%M:%S") print "\033[1;37;42m**** Sensor BMP280\033[0m",timeMark print '**** Luftdruck: {0:0.2f}hPa, Temp. (4): {1:0.1f} Grad'.format(pressure_nn,temperature_4) # # Update maximum and minimum pressure value and display L7f.configure(text= "%.1f" %minPress + " " + "%.1f" %maxPress) # 7 Write data to terminal and display print '**** Sensor BMP280: Luftdruck: {0:0.2f}hPa, Temp. (4): {1:0.1f} Grad'.format(pressure_nn,temperature_4) # print "**** Sensor BMP280: %.2f hPa " %pressure_nn # 6 wait half a cycle time.sleep(delay4*60/2-1) # wait print "\033[1;37;42m**** Store Values to csv File\033[0m" import csv import sys csvfile = "temp.csv" # Definition of time format to be written to the csv files timeC = time.strftime("%d")+'-' +time.strftime("%H")+'-' +time.strftime("%M") data = [timeC,"","","","", round (pressure_nn,1), round(temperature_4,1) ] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=",", lineterminator = '\n') writer.writerow(data) # print "**** Run Pressure and time written to : ", data # Write pressure csv file for plotting csvfile = "tempPressure.csv" data = [timeC, round(pressure_nn,1),] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=" ", lineterminator = '\n') writer.writerow(data) # Write temperature csv file for plotting csvfile = "tempTempBMP280.csv" data = [timeC, round(temperature_4,1),] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=" ", lineterminator = '\n') writer.writerow(data) # Update maximum and minimum pressure value and display L7f.configure(text= "%.1f" %minPress + " " + "%.1f" %maxPress) # 9 Comparision between last measuring and actual value # rounded to make the trend indicator (canvas) less sensitive # round (pressureStore,1), (pressure_nn, 1) if round (pressureStore,1) <= round (pressure_nn + tolChange,1): L7g.configure(text= "steigend") canvasPressureUp = Canvas(labelFrame, width=canvas_width, height=canvas_height) canvasPressureUp.grid(column=3, row=15, pady=0) points = [0,0,canvas_width,canvas_height, canvas_width,0, canvas_height,0] canvasPressureUp.create_polygon(points, outline="green", fill='grey', width=3) else: time.sleep(3) if round (pressureStore,1) >= round (pressure_nn - tolChange, 1): L7g.configure(text= "fallend") # canvasPressureDown = Canvas(labelFrame, width=canvas_width, height=canvas_height) canvasPressureDown.grid(column=3, row=15, pady=0) points = [canvas_width,canvas_width,canvas_height, 0,0, canvas_height] canvasPressureDown.create_polygon(points, outline="green", fill='#04B431', width=3) else: time.sleep(3) if round (pressureStore,1) == round (pressure_nn,1): L7g.configure(text= "gleichbleibend") canvasSample = Canvas(labelFrame, width=canvas_width, height=canvas_height) canvasSample.grid(column=3, row=15, pady=0) points = [0,0,canvas_width,canvas_height/2, 0, canvas_height] canvasSample.create_polygon(points, outline="green", fill='light grey', width=3) else: time.sleep(3) # 10 Reset minimum and maximum pressure at startup and midnight hourDay = time.strftime("%H") if reset == 1 or hourDay == "00": maxPress = minPress = pressureStore = pressure_nn reset = 0 L7f.configure(text= "%.1f" %minPress + " " + "%.1f" %maxPress) print "**** Midnight or startup reset" else: time.sleep(3) # 11 Set minimum and maximum pressure if round (pressure_nn, 1) >= round (maxPress,1): (maxPress) = pressure_nn else: time.sleep(3) if round (pressure_nn, 1) <= round (minPress, 1): (minPress) = pressure_nn else: time.sleep(3) # 13 Debug - print previous pressure and actual pressure (roundet) # print "**** Debug", round(pressureStore, 3), "Stored value (pressureStore)" print "**** Debug", round(pressure_nn, 3), "Actual value (pressure_nn) " # store actual pressure for next cycle pressureStore = pressure_nn # 14 Delay 4 readout and sleep for half a cycle delay4 = Slider4.get() time.sleep(delay4*60/2-3) # 15 End of cycle, decrement repeat by repeat -=1 # print end of cycle print ("Thread: " + name + " completed") # ________________________ Terrasse (1) ___________________________ # Sensor 1 (DHT22) - Temperatatur und Luftfeuchtigkeit # **************************************************** # https://www.einplatinencomputer.com/raspberry-pi-temperatur-und-luftfeuchtigkeitssensor-dht22/ # # 1 Preset minimum delay between 2 readouts delay1 = 10 # 2 Start task 2 - Scan Sensor 2 (DHT22) twice def task1 (name, delay, repeat): """ Sensor 1 (DHT22) - Temperatatur und Luftfeuchtigkeit """ # 3 Preset local variables for minimum/maximum indicator import csv import sys import os time.sleep(2) maxTout = 00.0 minTout = 00.0 reset = 1 midnightReset = 1 print ("Thread for: " + name + " started") print "\033[1;37;41m* Outdoor Temperature/Humidity\033[0m" # Initial read and display outdoor temp humidity, temperature = Adafruit_DHT.read_retry (Adafruit_DHT.DHT22, 4) time.sleep(2) L3a.configure(text= "%.1f" %temperature+ " ") L4a.configure(text= "%.0f" % humidity + " %") time.sleep(2) # 4 # Count down variable 'repeat' until 0 while repeat > 0: timeMark = time.strftime("%H:%M:%S") print "* Tread 1 Time at Start: ",timeMark # 5 Read value for slider 1 in seconds delay1 = Slider1.get() # 6 Read outdoor sensor DHT22 and print values to terminal # Readout temperature and humidity, sensor Adafruit_DHT.DHT22, gpio = 04 # sensor = Adafruit_DHT.DHT22, gpio = 4 humidity, temperature = Adafruit_DHT.read_retry (Adafruit_DHT.DHT22, 4) time.sleep(5) # WA06 Next code lines to check for possible sporadic error messages from Adafruit # Check if variable is string using type() # result = type(humidity) == str # print("Is readout a failure string ? : " + str(result)) # # Output: # Is readout a failure, a string ? : True # # # Clean up GPIO settings GPIO.cleanup(4) print "\033[1;37;41m* Outdoor Sensor DHT22 Readout 1\033[0m" # print '* Terrasse 1st Temperatur: {0:0.2f}*C Luftfeuchtigkeit: {1:0.1f} %'.format(temperature,humidity) # print (name + ": " + str(time.ctime(time.time()))) # 7 Insert outdoor temperature abd humidity into display (Label L3a) L3a.configure(text= "%.1f" %temperature+ " ") L4a.configure(text= "%.0f" % humidity + " %") # 8 Reset minimum and maximum temperature at startup hourDay = time.strftime("%H") if reset == 1 or hourDay == "00": maxTout = minTout = temperature reset = 0 L3b.configure(text= "%.1f" %minTout + " " + "%.1f" %maxTout) print "* Midnight or startup reset" else: time.sleep(3) time.sleep(delay1*60/2-3) # 9 wait for half cycle # 10 Second readout temperature and humidity humidity2, temperature2 = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 4) time.sleep(2) # Clean up GPIO settings GPIO.cleanup(4) # WA 10 # Elimination of sporadic false measurement of the DHT22 mainly 'outdoor' # It happens about once a day at intervalls of 2 minutes limitUpper= 1.06 + delay1*0.01 limitLower= 0.94 - delay1*0.01 print "Limits =" , limitUpper, limitLower if round (humidity2,1) > round (humidity,1)* limitUpper or round (humidity2,1)< round (humidity,1)* limitLower or round (temperature2,1)< round (temperature,1)* limitLower or round (temperature2,1)> round (temperature,1)*limitUpper: csvfile = "failureOUT.csv" data = [timeC,round(temperature2,1), round (humidity2,1) ] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=" ", lineterminator = '\n') writer.writerow(data) else: print "no failure outdoor humidity" # 11 Write data to a csv file (temp.csv) in the program folder import csv import sys csvfile = "tempTemp.csv" if humidity is not None and temperature is not None: humidity = round(humidity, 2) temperature = round(temperature, 2) print "\033[1;37;41m* Outdoor Sensor DHT22 Readout 2\033[0m" print '* Run 2 Temperature = {0:0.1f}*C Humidity = {1:0.1f}%'.format(temperature, humidity) else: print '* Run 2 no connection to the sensor !' csvfile = "temp.csv" timeC = time.strftime("%d")+'-' +time.strftime("%H")+'-' +time.strftime("%M") data = [timeC,temperature, humidity ] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=",", lineterminator = '\n') writer.writerow(data) time.sleep(2) csvfile = "outdoor.csv" data = [timeC,round(temperature2,1), round (humidity2,1) ] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=" ", lineterminator = '\n') writer.writerow(data) # print "* Run 2 Temperatur, humidity and time written to : ", data time.sleep(2) # 12 Print temperatur and humidity print '* Run 2 Sensor DHT22: Terrasse 2nd Temperatur: {0:0.2f}*C Luftfeuchtigkeit: {1:0.1f}%'.format(temperature2,humidity2) # print (name + ": " + str(time.ctime(time.time()))) # 13 Insert temperature into display (Label L3a) L3a.configure(text= "%.1f" %temperature2+ " ") # Aussentemperatur L4a.configure(text= "%.0f" % humidity2 + " %") # Aussenfeuchtigkeit # Alternative programming # get a new reading # dht22.trigger() # save our values # humidity = "%.f"(dht22.humidity()) # temp = "%.f" % (dht22.temperature()) # print ("temperature is: " + temperature + "C" ) # L3b.configure(text= "%.1f" %minTout + " " + "%.1f" %maxTout) # Update maximum and minimum temperature value and display if temperature2 >= maxTout: (maxTout) = temperature2 print "* Run 2 New Maximum Temperature Terrasse" else: time.sleep(1) if temperature2 <= minTout: (minTout) = temperature2 print "* Run 2 New Minimum Temperature Terrasse" else: time.sleep(1) # Insert to display L3b.configure(text= "%.1f" %minTout +" " + "%.1f" %maxTout) # canvas symbol positive or negative according to tendency if temperature2 >= temperature * 1.01: # temperatur lowered (delayed by 1 cycle) - canvas symbol not filled canvasTempUp = Canvas(labelFrame, width=canvas_width, height=canvas_height) canvasTempUp.grid(column=3, row=3, sticky=N, pady=0) points = [0,0,canvas_width,canvas_height, canvas_width,0, canvas_height,0] canvasTempUp.create_polygon(points, outline=syscolor, fill='light grey', width=3) else: canvasTempDown = Canvas(labelFrame, width=canvas_width, height=canvas_height) canvasTempDown.grid(column=3, row=3, sticky=N, pady=0) points = [0,canvas_height,canvas_height ,canvas_width,canvas_width ,0] canvasTempDown.create_polygon(points, outline=syscolor, fill='#F5A9A9', width=3) time.sleep(delay1*60/2-3) # get the hour of the current day hourDay = datetime.datetime.now().hour hourDay = time.strftime("%H") print ( name + "Full hour " + hourDay + " o'clock passed") # print hour for 24 storage repeat -=1 # decrement repeat by print ("Thread: " + name + " completed") # ________________________ Wohnung (2) ___________________________ # Sensor 2 (DHT22) - Temperatatur und Luftfeuchtigkeit # **************************************************** # 1 Preset minimum delay between 2 readouts delay2 = 10 # 2 Start task 2 - Scan Sensor 2 (DHT22) twice def task2 (name, delay, repeat): """ Sensor 1 (DHT22) - Temperatatur und Luftfeuchtigkeit """ # 3 Preset local variables for minimum/maximum indicator import csv import sys import os time.sleep(10) maxTin = 00.0 minTin = 00.0 reset = 1 print ("Thread for: " + name + " started") print "\033[1;37;41m** Indoor Temperature/Humidity\033[0m" # Initial read and display outdoor temp humidity, temperature = Adafruit_DHT.read_retry (Adafruit_DHT.DHT22, 17) time.sleep(3) L5a.configure(text= "%.1f" %temperature+ " ") L6a.configure(text= "%.0f" % humidity + " %") time.sleep(4) # 4 # Count down variable 'repeat' until 0 while repeat > 0: # timeMark = time.strftime("%H:%M:%S") # print "** Tread 2 Time at Start: ",timeMark # 5 Read value for slider 2 in seconds delay2 = Slider2.get() # 6 Readout 1 of temperature and humidity humidity, temperature = Adafruit_DHT.read_retry (Adafruit_DHT.DHT22, 17) # Clean up GPIO settings GPIO.cleanup(17) # 7 Printout 1 temperature and humidity to terminal print "\033[1;37;41m* Indoor Sensor DHT22 Readout 1\033[0m" print '** Run 1 Sensor DHT22: Wohnung Temperatur: {0:0.2f}*C Luftfeuchtigkeit: {1:0.1f}%'.format(temperature,humidity) # print (name + ": " + str(time.ctime(time.time()))) # 8 Insert values to display position L5a and L6a L5a.configure(text= "%.1f" %temperature + " ") L6a.configure(text= "%.0f" % humidity + " %") # Reset minimum and maximum pressure at startup and midnight hourDay = time.strftime("%H") if reset == 1 or hourDay == "00": maxTin = minTin = temperature reset = 0 L3c.configure(text= "%.1f" %minTin + " " + "%.1f" %maxTin) print "** Midnight or startup reset" else: time.sleep(3) # wait # 9 Delay of half a cycle to wait for 2nd readout time.sleep(delay2*60/2-1) # 10 second readout of temperature2 and humidity2 humidity2, temperature2 = Adafruit_DHT.read_retry(Adafruit_DHT.DHT22, 17) # Clean up GPIO settings GPIO.cleanup(17) # 11 Print to terminal print "\033[1;37;41m* Indoor Sensor DHT22 Readout 2\033[0m" # print '** Run 2 Sensor DHT22: Wohnung Temperatur: {0:0.2f}*C Luftfeuchtigkeit: {1:0.1f}%'.format(temperature2,humidity2) # print (name + ": " + str(time.ctime(time.time()))) # WA 10 # Elimination of sporadic false measurement of the DHT22 mainly 'outdoor' # It happens about once a day at intervalls of 2 minutes # This workaround filters this peaks # Factor: base value of 10% plus interval times 1% limitUpper= 1.06 + delay2*0.01 limitLower= 0.94 - delay2*0.01 print "Limits =" , limitUpper, limitLower if round (humidity2,1) > round (humidity,1)* limitUpper or round (humidity2,1)< round (humidity,1)* limitLower or round (temperature2,1)< round (temperature,1)* limitLower: csvfile = "failureIN.csv" data = [timeC,round(temperature2,1), round (humidity2,1) ] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=" ", lineterminator = '\n') writer.writerow(data) else: # Write data to file csvfile = "home.csv" timeHome = time.strftime("%d")+'-' +time.strftime("%H")+'-' +time.strftime("%M") # correction for use without a sensor data = [timeHome, "","" , round(temperature,1), round (humidity,1) ] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=" ", lineterminator = '\n') writer.writerow(data) # print "** Run 2 Temperatur, humidity and time written to : ", data csvfile = "temp.csv" timeC = time.strftime("%d")+'-' +time.strftime("%H")+'-' +time.strftime("%M") data = [timeC,"","", round(temperature,1), round(humidity,1) ] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=",", lineterminator = '\n') writer.writerow(data) # print "** Run 2 Temperatur, humidity and time written to : ", data # 12 Insert 2nd readout to display position L5a and L6a L5a.configure(text= "%.1f" %temperature2 + " ") # Innentemperatur L6a.configure(text= "%.0f" % humidity2 + " %") # Innenfeuchtigkeit # 13 canvas symbol positive or negative according to tendency if temperature2 >= temperature: # temperatur lowered (delayed by 1 cycle) - canvas symbol not filled canvasTempUp = Canvas(labelFrame, width=canvas_width, height=canvas_height) canvasTempUp.grid(column=3, row=6, sticky=N, pady=0) points = [0,0,canvas_width,canvas_height, canvas_width,0, canvas_height,0] canvasTempUp.create_polygon(points, outline=syscolor, fill='light grey', width=3) else: # temperatur raised (delayed by 1 cycle) - canvas symbol filled canvasTempDown = Canvas(labelFrame, width=canvas_width, height=canvas_height) canvasTempDown.grid(column=3, row=6, sticky=N, pady=0) points = [0,canvas_height,canvas_height ,canvas_width,canvas_width ,0] canvasTempDown.create_polygon(points, outline=syscolor, fill='#F5A9A9', width=3) # 14 Delay of half a cycle time.sleep(delay2*60/2) # 15 Update maximum and minimum temperature value and display (delayed) if temperature2 >= maxTin: (maxTin) = temperature2 else: time.sleep(2) if temperature2 <= minTin: (minTin) = temperature2 else: time.sleep(2) # prov. in diesem Loop L3c.configure(text= "%.1f" %minTin +" " + "%.1f" %maxTin) # 17 continue loop - # decrement repeat by 1 repeat -=1 # 18 End loop (2) print ("Thread: " + name + " completed") # ______________________________________________________________________ # ******************************************** # Miscellaneous LED, Options: Midnight reset, ... # ******************************************** # delay3 = 0.2 def task3 (name, delay, repeat): """ miscellaneous, such as LED blinker, gaz alarm """ print ("Thread for: " + name + " started") print "\033[1;37;40m*** LED started\033[0m" import csv import sys import os time.sleep(5) MidnightReset = 1 MidnightRepeat = 29 # count down repeat until 0 while repeat > 0: # Blue LED on # GPIO.output(17, GPIO.HIGH) print "\033[1;37;40m***\033[0m", name # delay3 = Slider3.get() time.sleep(1) # Be LED off # GPIO.output(17, GPIO.LOW) import datetime # get date and time eingabeDatum = time.strftime("%d.%m.%Y") eingabeZeit = time.strftime("%H:%M") # eingabeZeit = str(time.ctime()) # ctime # date and time to display to display L2.configure(text= eingabeDatum) L2a.configure(text= eingabeZeit) leftLabelRevision.configure (text= panel, fg =syscolor) # midnight serenade - get the hour of the current day midnight = datetime.datetime.now().hour midnight = time.strftime("%H:%M") # midnight serenade - reset csv files if button set if midnight == "00:00" and B10["text"] == "Reset Ein" : print name, "*** It's midnight, reset csv files and wait for 60 sec" # Reset csv files data = [0.0, 0.0, 0.0] # Clear csv files csvFiles = ["temp.csv","tempCPU.csv", "outdoor.csv", "home.csv", "tempPressure.csv","tempTempBMP280.csv", "tempGas.csv"] for file in csvFiles: weatherData = open((file), "w") weatherData.truncate() print "Mainloop: Cleared files: ", (file) # Definition of time format to be written to the other csv files data = ["Recorded Time","Outdoor T","Outdoor H","Indoor T","Indoor H", "Pressure","BMP280 T",1 ] with open("temp.csv", "a")as output: writer = csv.writer(output, delimiter=",") writer.writerow(data) print "Mainloop: Header line written to : ", data time.sleep(60) else: time.sleep(1) (MidnightRepeat) = MidnightRepeat -1 if MidnightRepeat == 0: MidnightRepeat = 25 midnight = time.strftime("%H:%M") print "\033[1;37;49m***\033[0m", name, "Time now: ",midnight, " - wait for next Midnight Reset" else: leftLabelRevision.configure (text= "Basisversion", fg ="light grey") # decrement repeat by 1 repeat -=1 print ("Thread: " + name + " completed") # ______________________________________________________________________ # probleme mit import matplotlib # Programm laeuft auf GEANY, nicht aber omline import matplotlib matplotlib.use('TkAgg') from matplotlib.pyplot import * repeat = 6 # ******************************************** # CPU temperatur readout and display to screen # ******************************************** # def task5 (name, delay, repeat): """ Readout CPU temperature and plot """ from gpiozero import CPUTemperature from time import sleep, strftime, time import matplotlib.pyplot as plt # Delay before start of task 5 sleep(80) print ("***** Thread for: " + name + " started") print "\033[1;31;37m***** CPU Temperature Monitor started\033[0m" # Start of task 5 - count down repeat until 0 while repeat > 0: # original cpu readout cpu = CPUTemperature(min_temp=50, max_temp=90) cpuTemp = round (cpu.temperature,1) # print "***** Thread 5: CPU Temperatur = ",cpuTemp," *C" print "\033[1;31;37m***** CPU Temperature = \033[0m" ,cpuTemp," *C" leftLabelCPU.configure(text= "CPU Temp = " + str(cpuTemp) + " *C" ) # Write CPU temperature csv file for plotting import csv import sys import os import time csvfile = "tempCPU.csv" timeCPU = time.strftime("%d")+'-' +time.strftime("%H")+'-' +time.strftime("%M") data = [timeCPU, round(cpuTemp,1),] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=" ", lineterminator = '\n') writer.writerow(data) if cpuTemp >= 60: # Play alarm sound for 10 seconds from pygame import mixer mixer.init() mixer.music.load("evacuate.mp3") # -1 to loop the sound mixer.music.play(-1) time.sleep(10) #let it play for 10 seconds mixer.music.stop() sleep(300) # decrement repeat by 1 repeat -=1 print ("Thread: " + name + " completed") # ******************************************** # Gas Sensor # ******************************************** # def task6 (name, delay, repeat): """ Readout CPU temperature and plot """ # Delay before start of task 6 and preset cycle time import time time.sleep(20) cycle = 180 fresh_air = 3 # print ("****** Thread for: " + name + " started") print "\033[1;37;44m****** Gas Monitor started\033[0m" # Start of task 6 - count down repeat until 0 while repeat > 0: print "\033[1;37;44m****** Gas Monitor running\033[0m" time.sleep(10) L8a.configure(text= "Gut 2..5", fg = "green" ) # Start fart detectot script import time, RPi.GPIO as GPIO from pygame import mixer mixer.init() mixer.music.load("evacuate.mp3") alarm_template = "\033[5;47;44m{0} {1} {2}\033[0m" TRIGGER = 25 GPIO.setwarnings(False) # use BCM pin layout GPIO.setmode(GPIO.BCM) GPIO.setup(TRIGGER, GPIO.IN) def set_pin(pin, ison): if ison: GPIO.setup(pin, GPIO.OUT) GPIO.output(pin, GPIO.LOW) else: GPIO.setup(pin, GPIO.IN) # GPIO 17 to be set to a free pin def set_dac(bitwise): # Original script 17, 18,22,23 - 17 set to 24 set_pin(24, bitwise & 1 == 1) set_pin(18, bitwise & 2 == 2) set_pin(22, bitwise & 4 == 4) set_pin(23, bitwise & 8 == 8) def calibrate(trace = False, sleep_time = 0): result = -1 for i in range(0, 16): set_dac(i) if trace: # print binary format L8c.configure(text= i ) print i, "{0:b}".format(i) time.sleep(sleep_time) if not GPIO.input(TRIGGER): result = i break return result while True: fresh_air = calibrate(trace = True, sleep_time = 0.5) if fresh_air != -1: print "Kalibriert zu:", fresh_air L8b.configure(text= "Kalibriert", fg = "blue") # L8a ["text" ] = "Gut" start_time = time.time() print "\033[1;37;44m****** Waiting for Gas: CH4(Methan),CO, ... \033[0m" # print "Waiting for gas..." # wait as long as trigger is LOW or < 2 min while not GPIO.input(TRIGGER) and time.time() - start_time < cycle: time.sleep(.1) # make sure this is not just a timeout if time.time() - start_time < cycle: # quickly recalibrate to get the gas level gas = calibrate(sleep_time = .1) L8a.configure(text= "Gut", fg = "green" ) if gas > fresh_air or gas == -1: if gas >= 0 and gas < 5: print alarm_template.format("Gut", gas, "Level 0 bis 6") L8a.configure(text= "Check !", fg = "green" ) elif gas >= 5 and gas < 10: print alarm_template.format("Check !", gas, "detected!") L8a.configure(text= "5 .. 10", fg = "#FF8000") mixer.music.play(-1) time.sleep(20) mixer.music.stop() elif gas >= 10 and gas < 15: print alarm_template.format("Gefahr", gas, "detected!") L8a.configure(text= "Gefahr", fg = "red" ) elif gas == -1: print alarm_template.format("Alarm", "extrem", "DETECTED! EVACUATE !") L8a.configure(text= "Alarm", fg = "red" ) # -1 to loop the sound mixer.music.play(-1) # let ithe alarm play for 20 seconds time.sleep(20) mixer.music.stop() else: print "\033[1;37;44m****** Time out, recalibrating...\033[0m" cycle = Slider3.get() * 60 import csv import sys import os # i = index for air quality, lowest is best, e.g. 2 or 3 index= (fresh_air) csvfile = "tempGas.csv" timeGas = time.strftime("%d")+'-' +time.strftime("%H")+'-' +time.strftime("%M") data = [timeGas, index,] with open(csvfile, "a")as output: writer = csv.writer(output, delimiter=" ", lineterminator = '\n') writer.writerow(data) print "\033[1;37;44m****** Index: \033[0m" ,index else: print "\033[1;37;44m****** Could not calibrate\033[0m" # Send inf to panel L8b.configure(text= "NOT calibr.", fg = syscolor ) time.sleep(50) # decrement repeat by 1 repeat -=1 print ("Thread: " + name + " completed") # ______________________________________________________________________ # Beispiel: Quasi-Paralleles Schreiben von Zeit und Datum (4 Teilprozesse) # 4 Threads, 3 to print Date and Time # Definition der Teilprozesse (Threads) scan1 = Thread (target=task1, args=("***** Thread Terrasse Sensor(1)",delay1,100000)) scan2 = Thread (target=task2, args=("***** Thread Wohnung (2)",delay2,100000)) scan3 = Thread (target=task3, args=("LED(3)",delay3,6000000)) scan4 = Thread (target=task4, args=("***** Thread Luftdruck (4)",delay4,100000)) scan5 = Thread (target=task5, args=("***** Thread (5)",300,100000)) scan6 = Thread (target=task6, args=("***** Thread (5)",300,100000)) print "" print "*******************" print " Start all Threads " print "*******************" print "" # Start Threads 1 to 5 scan1.start() scan2.start() scan3.start() scan4.start() scan5.start() scan6.start() root.mainloop() # GUI will be updated. # No elements after this line