#(c)2017 Jannik Seiler & Hendrik Schutter #036 from picamera import PiCamera from time import sleep from ftplib import FTP from fractions import Fraction from datetime import datetime import ftplib import time import os from collections import namedtuple import logging import configparser import subprocess from spidev import SpiDev from time import sleep configParser = configparser.RawConfigParser() configFilePath = r'/home/pi/config.txt' configParser.read(configFilePath) version = 'starting camera version 036' print(version) print('reading config...') ftp_url = configParser.get('config', 'ftp_url') ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') ftp_log_directory = configParser.get('config', 'ftp_log_directory') ftp_user = configParser.get('config', 'ftp_user') ftp_pw = configParser.get('config', 'ftp_pw') picture_directory = configParser.get('config', 'picture_directory') log_directory = configParser.get('config', 'log_directory') camera_number = configParser.get('config', 'camera_number') enable_modem = configParser.get('config', 'enable_modem') picture_size = int(configParser.get('config', 'picture_size')) internet = configParser.get('config', 'internet') modem_apn = configParser.get('config', 'modem_apn') upload_only = int(configParser.get('config', 'upload_only')) interval = int(configParser.get('config', 'interval')) ioBoard = configParser.get('config', 'I/O_Board') print('done!') wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] print('initializing logger...') log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' log_name = log_name.replace(" ","-") reconnect_counter = 0 logging.getLogger('').handlers = [] logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') logging.info(version) print('done') print('reading picture number...') try: f = open("/home/pi/picture_Number.txt",'r') picture_number = int(f.read()) f.close() except Exception as ea: print('No picture_Number.txt found. Creating new .. ') f = open("/home/pi/picture_Number.txt",'w') f.write(str(0)) f.close() f = open("/home/pi/picture_Number.txt",'r') picture_number = int(f.read()) f.close() logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') print('done, picture number is:',str(picture_number)) print('sleeping for 15 seconds until boot is finished!') sleep(15) camera = PiCamera() upload_every = upload_only if ioBoard =="true": print('Running with the nice IO board!') spi = SpiDev() spi.open(0,0) else: print('Running without the nice IO board!') if internet == 'true': print('Running in Online mode, internet connection is required') try: ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) ftp.cwd(ftp_picture_directory) except Exception as ea: print('no internet connection on startup trying to reconnect later!') print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) else: print('Running in Offline mode, no internet connection is required') #camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 #camera.shutter_speed = 500000 camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 camera.awb_mode = 'auto' camera.exposure_mode = 'auto' #camera.brightness = 50 #0 bis 100; default 50 #camera.contrast = 0 #-100 bis 100; default 0 #camera.iso = 0 #0 bis 1600; default 0(auto) #camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) #camera.sharpness = 0 #-100 bis 100; default 0 #get cpu temperature def getCpuTemperature(): tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) cpu_temp = tempFile.read() tempFile.close() return float(cpu_temp)/1000 #uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over def uploadToFTP(): print('trying to upload file ...') logging.info('trying to upload file ...') try: ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) ftp.sendcmd('SITE CHMOD 754 '+picture_name) os.remove(picture_path) print('upload successful!') logging.info('upload successful!') except ftplib.all_errors as e: print ('upload failed!') print (e) logging.error('upload failed!') logging.error(str(e)) try: print('[FTP]trying to reconnect ...') logging.info('[FTP]trying to reconnect ...') ftp.connect(ftp_url) ftp.login(ftp_user,ftp_pw) ftp.cwd(ftp_picture_directory) print('[FTP]re-connecting successful!') logging.info('[FTP]re-connecting successful!') ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) ftp.sendcmd('SITE CHMOD 754 '+picture_name) os.remove(picture_path) print('[FTP]upload successful!') logging.info('[FTP]upload successful!') except ftplib.all_errors as e9: print('[FTP]re-connecting failed!') print(e9) logging.error('[FTP]re-connecting failed!') logging.error(str(e9)) try: stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') print('[sakis3g]Network Status: ' + stdoutdata) logging.info('[sakis3g]Network Status: ' + stdoutdata) if enable_modem == 'true' and 'Nicht' in stdoutdata: print('[sakis3g]not connected, trying to reconnect') logging.info('[sakis3g]not connected, trying to reconnect') stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") print(stdoutdata) logging.info(stdoutdata) logging.info('[sakis3g] disconnected') stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") print(stdoutdata) print('[sakis3g]reconnection successful') logging.info(stdoutdata) logging.info('[sakis3g]reconnection hopefully successful') else: print('[sakis3g]if this appears you are connected or there is a bug!') logging.info('[sakis3g]if this appears you are connected or there is a bug!') except Exception as e3: print(str(e3)) logging.error(str(e3)) #try? check inet connection -> /usr/bin/modem3g/sakis3g status # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' # danach nochmal status if dann status = nicht dann reboot return def checkDiskSpace(): st = os.statvfs('/media/usb0') free = st.f_bavail * st.f_frsize total = st.f_blocks * st.f_frsize freePercentaged = int(((st.f_bavail * st.f_frsize)/(st.f_blocks * st.f_frsize))*100) logging.info('Free disk space ' +str(freePercentaged)+' %') print('Free disk space ',str(freePercentaged),' %') if freePercentaged < 20 and freePercentaged > 10: logging.warning('Storage Drive nearly full!') if freePercentaged < 10: logging.critical('Storage Drive full, Backup Space in use!') return def checkCpuTemperature(): if getCpuTemperature() <= -5.0: logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') elif getCpuTemperature() <= 5.0: logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') elif getCpuTemperature() >= 45.0: logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') elif getCpuTemperature() >= 50.0: logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') else: logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') return def readMPC(channel): adc = spi.xfer2([1, (8 + channel) << 4, 0]) data = ((adc[1] & 3) << 8) + adc[2] return data def sleepToNextPicture(): time_sleep_unix = time_next_unix - time.time() if time_sleep_unix>0: print("sleeping now",time_sleep_unix,"seconds"+'\n') logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') sleep(time_sleep_unix) else: print('no sleep needed, behind schedule!') logging.warning('no sleep needed, behind schedule!') return def checkSystemVoltage(): systemVoltage = (((readMPC(0) / 1023.0 * 3.3)*6.62)*0.95) print("System Input Voltage: %.2f" % systemVoltage, "Volt") logging.info('System Input Voltage: ' + str("%.2f" % systemVoltage) + ' Volt') if systemVoltage < 11.3 and systemVoltage > 9: logging.warning('Low System Input Voltage! Maybe bad power supply or no sun.') if systemVoltage < 9: logging.critical('Very low System Input Voltage! Bad power supply or no sun.') return #main programm (endless loop) while 1: time_next_unix = time.time() + interval #time for next picture time_name = time.asctime(time.localtime(time.time())) #get time for picture_name time_name = time_name.replace(" ","_") time_name = time_name.replace(":","-") picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' picture_path = picture_directory + picture_name print ("Time:", time_name) try: camera.exif_tags['IFD0.Make'] = 'CopterSicht' camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' camera.exif_tags['IFD0.ShutterSpeedValue '] = '' camera.exif_tags['IFD0.ISOSpeedRatings '] = '' camera.exif_tags['IFD0.WhiteBalance '] = '' camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) picture_number += 1 #increase picture_number print('picture_number:',str(picture_number)) f = open("/home/pi/picture_Number.txt",'w') f.write(str(picture_number)) #save picture_number to a text file f.close() except Exception as e2: logging.error(str(e2)) print ('Picture size:',os.path.getsize(picture_path),"Byte") logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') checkDiskSpace() if ioBoard =="true": checkSystemVoltage() if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep print ('it seems to be night!') logging.info('it seems to be night!') midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep print ('cannot be night!') logging.warning('cannot be night!') print("uploadTimer",upload_every) if (internet == 'true')and(upload_every == 1): uploadToFTP() upload_every = upload_only else: upload_every -= 1 logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') print('Skipping upload. Next upload in',(upload_every),'pictures') checkCpuTemperature() sleepToNextPicture() else: os.remove(picture_path) #deleting picture because it's night! picture_number -= 1 #decrease picture_number print('picture_number:',str(picture_number)) f = open("/home/pi/picture_Number.txt",'w') f.write(str(picture_number)) #save picture_number to a text file f.close() #uploading log file print ('skipping picture upload!') print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') if internet == 'true': print('uploading todays log befor going to sleep!') logging.info('skipping picture upload!') logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') if internet == 'true': logging.info('uploading todays log befor going to sleep!') if internet == 'true': try: ftp.cwd(ftp_log_directory) ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) ftp.sendcmd('SITE CHMOD 754 '+log_name) print('uploaded log-file successful!') logging.info('uploaded log-file successful!') except ftplib.all_errors as e: print ('upload failed!') print (e) logging.error('upload failed!') logging.error(str(e)) try: print('[FTP]trying to reconnect ...') logging.info('[FTP]trying to reconnect ...') ftp.connect(ftp_url) ftp.login(ftp_user,ftp_pw) print('[FTP]re-connecting ftp successful!') logging.info('[FTP]re-connecting ftp successful!') ftp.cwd(ftp_log_directory) ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) ftp.sendcmd('SITE CHMOD 754 '+log_name) print('uploaded log-file successful!') logging.info('uploaded log-file successful!') except ftplib.all_errors as e8: print('[FTP]re-connecting failed!') print(e8) logging.error('[FTP]re-connecting failed!') logging.error(str(e8)) try: stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') print('[sakis3g]Network Status: ' + stdoutdata) logging.info('[sakis3g]Network Status: ' + stdoutdata) if enable_modem == 'true' and 'Nicht' in stdoutdata: print('[sakis3g]not connected, trying to reconnect') print('[sakis3g]not connected, trying to reconnect') logging.info('[sakis3g]not connected, trying to reconnect') stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") print(stdoutdata) logging.info(stdoutdata) logging.info('[sakis3g] disconnected') stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") print(stdoutdata) print('[sakis3g]reconnection successful') logging.info(stdoutdata) logging.info('[sakis3g]reconnection hopefully successful') try: ftp.connect(ftp_url) ftp.login(ftp_user,ftp_pw) print('re-connecting ftp successful!') logging.info('re-connecting ftp successful!') ftp.cwd(ftp_log_directory) ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) ftp.sendcmd('SITE CHMOD 754 '+log_name) print('uploaded log-file successful!') logging.info('uploaded log-file successful!') except Exception as e4: print(str(e4)) logging.error(str(e4)) else: print('[sakis3g]if this appears you are connected or there is a bug!') logging.info('[sakis3g]if this appears you are connected or there is a bug!') except Exception as e3: print(str(e3)) logging.error(str(e3)) #try? check inet connection -> /usr/bin/modem3g/sakis3g status # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' # danach nochmal status if dann status = nicht dann reboot try: ftp.cwd(ftp_picture_directory) except Exception as er: print('could not change ftp directory !') logging.error('could not change ftp directory !') print(str(er)) logging.error(str(er)) #sleep until next morning print ('going to sleep for a while ...') logging.info('going to sleep for a while ...') midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) seconds = (datetime.now() - midnight).seconds #seconds since midnight if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds else: #if time between wakeup_Time and 12pm sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') sleep(sleep_time-10) #wake up 10 seconds before we should for exact start print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): sleep(0.5) log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' log_name = log_name.replace(" ","-") logging.getLogger('').handlers = [] logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') print('slept for '+str(sleep_time)+' seconds') print('Time to wakeup! \n') logging.info('slept for '+str(sleep_time)+' seconds') logging.info('Time to wakeup! \n') else: if (internet == 'true')and(upload_every == 1): uploadToFTP() upload_every = upload_only else: upload_every -= 1 logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') print('Skipping upload. Next upload in',upload_every,'pictures') checkCpuTemperature() sleepToNextPicture()