# Python 3 program to access OpenWeatherMap.org (OWM) via custom API # and to access an Arduino via serial port (USB A Arduino, USB B RPi) # Indoor temp. from Arduino (DHT11 sensor), Outdoor temp. via RPi (OWM) # Store time/temperature data to Google Sheets via custom APIs # Read statistical summary cell data from Google Sheets # Blink LEDs connected to RPi as needed # ref.: prior RPi projects at: # http://www.cantlinmath.com/raspberrypi_resources/rpi_resources.htm # Mr. C. 10-18-2020 # ***************************************************************** # OWM data: # "id": 4081671, "name": "Oneonta", "state": "AL", "country": "US", # "coord": {"lon": -86.472763,"lat": 33.948151} # "id": 4830707, "name": "Ashville", "state": "AL", "country": "US", # "coord": {"lon": -86.254417, "lat": 33.83704} # ***************************************************************** # JSON file w/Google Credentials in local folder: rpiowmdata.json # ***************************************************************** # Libraries from gpiozero import LED from pyowm.owm import OWM #OpenWeatherMap Library import datetime, time import gspread #Google Sheets Library from oauth2client.service_account import ServiceAccountCredentials import serial # Get Serial Data From Arduino # open the RPi serial port, timeout is in seconds, Arduino will take some time to stabilize # read the serial data from the Arduino in Python type byte and decode it to a string then # after some cleanup into floating point variable for indoor RH and temperature (deg. F) # Serial data from Arduino using serial.print() versus serial.write() is probably ascii encoded # for this simple numeric data and text data utf-8 encoding at the Python end should work for ascii ser = serial.Serial('/dev/ttyACM0', 9600, timeout=30) # establish serial port connection to Arduino ser.flushInput() # clear the serial port queue time.sleep(1) # allow a short time to stabilize ser_bytes = ser.readline() # read the incoming data, ser_bytes will be type bytes ex: b'35.00,75.20\r\n' ser_string1 = ser_bytes.decode('utf-8') # convert utf-8 byte data to type string ser_string2 =ser_string1.rstrip() # strip spaces and the carriage return and new line characters \r\n ser_list = ser_string2.split(',') # split string into rh and temp values (separator,max splits) rh_indoor = float(ser_list[0]) # convert DHT11 RH data string into floating point t_indoor = float(ser_list[1]) # convert DHT11 temp data string into floating point time.sleep(10) # get initial Open Weather Map (OWM) data owm = OWM('xxxput your key herexxx') # Mr. C.'s OWM API Key mgr = owm.weather_manager() observation = mgr.weather_at_place('Oneonta,AL,US') # observation has all data weather = observation.weather temp_dict_fahrenheit = weather.temperature('fahrenheit') temp_now_oneonta = temp_dict_fahrenheit['temp'] # connect to Google Sheets scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive'] # Use custom JSON file downloaded from Google API Manager in next line creds = ServiceAccountCredentials.from_json_keyfile_name('rpiowmdata.json', scope) client = gspread.authorize(creds) # Use name of Google Sheets file used to store data in next line sheet = client.open("RPi_OWM_GS").sheet1 # print selected initial values of local variables to the Python console print("*"*80) print('initial conditions at Oneonta, AL') print(weather.status) print(weather.detailed_status) print(temp_dict_fahrenheit) print(temp_dict_fahrenheit['temp']) print("indoor rh and temp") print(rh_indoor) print(t_indoor) # Send initial outdoor temperature data to the Arduino t_outdoor = str(temp_now_oneonta) # convert floating point temp_now_oneonta to string t_outdoor = t_outdoor + "\n" # use the newline as an "end of data identifier" t_outdoor = t_outdoor.encode("utf-8") # convert string to byte type, ex: b '76.32\n' ser.write(t_outdoor) # setup GPIO ports on the RPi for LEDs rled = LED(25) # red led yled = LED(24) # yellow led gled = LED(23) # green led # function used to append temperature data to Google Sheets file def append_sheet(data,rh_in,t_in): time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f') print("*"*80) values =[time,data,rh_in,t_in] print(values) sheet.append_row(values) # start infinite loop while True: if temp_now_oneonta >= 90.00: yled.off() gled.off() rled.on() print('temp high ', temp_dict_fahrenheit['temp'], ' deg. F') time.sleep(15) elif temp_now_oneonta >= 60.00 and temp_now_oneonta < 90.00: rled.off() gled.off() yled.on() print('temp medium ', temp_dict_fahrenheit['temp'], ' deg. F') time.sleep(15) elif temp_now_oneonta < 60.00: rled.off() yled.off() gled.on() print('temp low ', temp_dict_fahrenheit['temp'], ' deg. F') time.sleep(15) # get new OWM data owm = OWM('xxxput your key herexxx') # Mr. C.'s OWM API Key mgr = owm.weather_manager() observation = mgr.weather_at_place('Oneonta,AL,US') #observation has all data weather = observation.weather temp_dict_fahrenheit = weather.temperature('fahrenheit') temp_now_oneonta = temp_dict_fahrenheit['temp'] time.sleep(5) # get new Arduino serial data ser = serial.Serial('/dev/ttyACM0', 9600, timeout=30) # establish serial port connection to Arduino ser.flushInput() # clear the serial port queue time.sleep(1) # allow a short time to stabilize ser_bytes = ser.readline() # read the incoming data, ser_bytes will be type bytes ex: b'35.00,75.20\r\n' ser_string1 = ser_bytes.decode('utf-8') # convert utf-8 byte data to type string ser_string2 =ser_string1.rstrip() # strip spaces and the carriage return and new line characters \r\n ser_list = ser_string2.split(',') # split string into rh and temp values (separator,max splits) rh_indoor = float(ser_list[0]) # convert DHT11 RH data string into floating point t_indoor = float(ser_list[1]) # convert DHT11 temp data string into floating point time.sleep(10) # update Google Sheets with new data client.login() # login to Google Sheets time.sleep(1) append_sheet(temp_now_oneonta,rh_indoor,t_indoor) # append data to Google Sheets # read data from Google Sheets std_dev_val = sheet.acell('D24').value mean_val = sheet.acell('E24').value med_val = sheet.acell('F24').value q1_val = sheet.acell('G24').value q3_val = sheet.acell('H24').value min_val = sheet.acell('I24').value max_val = sheet.acell('J24').value # send updated outdoor temperature data to the Arduino t_outdoor = str(temp_now_oneonta) # convert floating point temp_now_oneonta to string t_outdoor = t_outdoor + "\n" # use the newline as an "end of data identifier" t_outdoor = t_outdoor.encode("utf-8") # convert string to byte type ser.write(t_outdoor) # print selected local variables to the Python console print("*"*80) # print 80 asterisks print("Google Sheet Values In Infinite Loop") print('updated conditions at Oneonta, AL') print(weather.status) print(weather.detailed_status) print(temp_dict_fahrenheit) print(temp_dict_fahrenheit['temp']) print('Standard Deviation') print(std_dev_val) print('Mean') print(mean_val) print('Median') print(med_val) print('Quartile 1') print(q1_val) print('Quartile 3') print(q3_val) print('Minimum') print(min_val) print('Maximum') print(max_val) print("indoor rh and temp") print(rh_indoor) print(t_indoor) continue # endof infinite loop