Timelapse_Camera_Firmware/Software/ZK_python/camera_v4_041.py

558 lines
21 KiB
Python

# (c)2017 Jannik Seiler & Hendrik Schutter
# 041
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
import http.client as httplib
from collections import namedtuple
import logging
import configparser
import subprocess
from spidev import SpiDev
from time import sleep
import RPi.GPIO as GPIO
# 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 Exception 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 Exception as e9:
print('[FTP] re-connecting failed!')
print(e9)
logging.error('[FTP] re-connecting failed!')
logging.error(str(e9))
if reconnectToInternet() == 'true':
print('Reconnect successful')
logging.info('[Internet] Reconnect successful!')
else:
print('Reconnect failed')
logging.error('[Internet] Reconnect failed!')
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('[Disk] Free space: ' + str(freePercentaged) + ' %')
print('Free disk space ', str(freePercentaged), ' %')
if freePercentaged < 20 and freePercentaged > 10: logging.warning('[Disk] Storage Drive nearly full!')
if freePercentaged < 10: logging.critical('[Disk] Storage Drive full, Backup Space in use!')
return
def checkCpu():
cpuUsage = (os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip())
cpuUsage = (float(cpuUsage.replace(',', '.')))*25
print('[CPU] Usage: ',str("%.2f" % cpuUsage),' %')
logging.info('[CPU] Usage: '+ str("%.2f" % cpuUsage) + ' %')
if getCpuTemperature() <= -5.0:
logging.critical('[CPU] Coold: ' + str(getCpuTemperature()) + ' C')
elif getCpuTemperature() <= 5.0:
logging.warning('[CPU] Coold: ' + str(getCpuTemperature()) + ' C')
elif getCpuTemperature() >= 45.0:
logging.warning('[CPU] Hot: ' + str(getCpuTemperature()) + ' C')
elif getCpuTemperature() >= 50.0:
logging.critical('[CPU] Hot: ' + str(getCpuTemperature()) + ' C')
else:
logging.info('[CPU] 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('[Voltage] ' + str("%.2f" % systemVoltage) + ' Volt')
if systemVoltage < 11.3 and systemVoltage > 9:
logging.warning('[Voltage] Low System Input Voltage! Maybe bad power supply or no sun.')
if tvOut == 'auto':
stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ')
print('[TV Out] Status: ' + stdoutdata)
logging.info('[TV Out] Status: ' + stdoutdata)
if systemVoltage < 9: logging.critical('[Voltage] Very low System Input Voltage! Bad power supply or no sun.')
return
def reconnectToInternet():
try:
conn = httplib.HTTPConnection("www.google.de", timeout=5)
conn.request("HEAD", "/")
conn.close()
print('Internet connection established')
print('Server is maybe not online!')
logging.info('Internet connection established')
logging.error('Server maybe is not online!')
global interntTmp
interntTmp = 'true'
#checkConnectionToFTPServer()
return 'true'
except Exception as e2:
conn.close()
print('no Internet connection')
print('trying to reconnect to internet')
logging.error('no Internet connection!')
logging.info('trying to reconnect to internet')
if enable_modem == 'true':
print('[MODEM] no UMTS connection')
logging.error('[MODEM] no UMTS connection')
try:
stdoutdata = subprocess.getoutput('sudo /usr/bin/modem3g/sakis3g status')
print('[MODEM] Network Status: ' + stdoutdata)
logging.info('[MODEM] Network Status: ' + stdoutdata)
stdoutdata = subprocess.getoutput(
"sudo /usr/bin/modem3g/sakis3g disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'")
print(stdoutdata)
logging.info(stdoutdata)
logging.info('[MODEM] disconnected')
sleep(20)
stdoutdata = subprocess.getoutput(
"sudo /usr/bin/modem3g/sakis3g connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'")
print(stdoutdata)
print('[MODEM] reconnection successful attempt')
logging.info('[MODEM] reconnection successful attempt')
logging.info(stdoutdata)
sleep(10)
try:
conn = httplib.HTTPConnection("www.google.de", timeout=5)
conn.request("HEAD", "/")
conn.close()
print('Internet connection established')
logging.info('Internet connection established')
return 'true'
except Exception as e5:
conn.close()
print('[MODEM] UMTS connection failed')
logging.error('[MODEM] UMTS connection failed')
print(str(e5))
logging.error(str(e5))
return 'false'
except Exception as e4:
print('[MODEM] UMTS connection failed')
logging.error('[MODEM] UMTS connection failed')
print(str(e4))
logging.error(str(e4))
return 'false'
else:
print('LAN or WLAN not connected!')
logging.error('LAN or WLAN not connected!')
return 'false'
def checkConnectionToFTPServer():
try:
# ping ftp url instead something else
conn = httplib.HTTPConnection("www.google.de", timeout=5)
conn.request("HEAD", "/")
conn.close()
try:
global ftp
ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20)
ftp.cwd(ftp_picture_directory)
print('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd())
logging.info('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd())
global internetTmp
internetTmp = 'true'
global upload_every
upload_every = upload_only
except Exception as ea:
print('[FTP] no internet or ftp connection trying to reconnect later!')
logging.error('[FTP] no internet or ftp connection trying to reconnect later!')
print('[FTP] Server connection established')
logging.info('[FTP] Server connection established')
except Exception as e5:
conn.close()
print('[FTP] Server connection not established')
logging.info('[FTP] Server connection not established')
reconnectToInternet()
return
configParser = configparser.RawConfigParser()
configFilePath = r'/home/pi/config.txt'
configParser.read(configFilePath)
# ioBoard
piezo = 25
bootSwitch = 17
version = 'starting camera version 041'
print('Copyright CopterSicht - info@coptersicht.de 2015-2017')
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')
mute = configParser.get('config', 'mute')
wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',')
bed_Time = str(configParser.get('config', 'bed_Time')).split(',')
tvOut = configParser.get('config', 'TV_Output')
print('done!')
print('initializing logger...')
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')
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
internetTmp = internet
if ioBoard == "true":
print('Running with the nice IO board!')
spi = SpiDev()
spi.open(0, 0)
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(piezo, GPIO.OUT)
GPIO.setup(bootSwitch, GPIO.IN)
if GPIO.input(bootSwitch) == 0:
camera = PiCamera()
camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s
camera.start_preview()
# camera.start_preview(fullscreen=False, window = (100, 20, 960, 720))
print('---starting sharpness tool---')
print('--------normal output--------')
while GPIO.input(bootSwitch) == 0: sleep(1)
camera.stop_preview()
sleep(5)
if GPIO.input(bootSwitch) == 0:
camera.stop_preview()
print('---------zoom output---------')
camera.crop = (0.5, 0.5, 0.3, 0.4)
camera.start_preview()
while GPIO.input(bootSwitch) == 0: sleep(1)
camera.stop_preview()
else:
camera.stop_preview()
camera.close()
if mute == "false":
GPIO.output(piezo, GPIO.HIGH)
sleep(1)
GPIO.output(piezo, GPIO.LOW)
else:
print('Running without the nice IO board!')
if tvOut == 'false':
stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ')
print('[TV Out] Status: ' + stdoutdata)
logging.info('[TV Out] Status: ' + stdoutdata)
if internetTmp == 'true':
print('Running in Online mode, internet connection is required')
if enable_modem == 'true': reconnectToInternet()
try:
ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20)
ftp.cwd(ftp_picture_directory)
print('New ftp connection successful! current dicertory is: ' + ftp.pwd())
logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd())
except Exception as ea:
print('no internet or ftp connection on startup trying to reconnect later!')
logging.error('no internet or ftp connection on startup trying to reconnect later!')
internetTmp = 'false'
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.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
# 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)
camera = PiCamera()
camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s
camera.exposure_mode = 'auto'
camera.crop = (0, 0, 0, 0)
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'] = 'interval capture'
if mute == "false": GPIO.output(piezo, GPIO.HIGH)
print('Capturing image')
logging.info('[Camera] Capturing image')
camera.capture(picture_path) # capture image and save to picture_path (picture_directory + picture_name)
camera.close()
if mute == "false": GPIO.output(piezo, GPIO.LOW)
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('[Camera] Picture size: ' + str(os.path.getsize(picture_path)) + ' Byte')
checkDiskSpace()
if ioBoard == "true": checkSystemVoltage()
if os.path.getsize(picture_path) < picture_size:
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 > float(wakeup_Time[datetime.now().month - 1]) * 60 * 60 and seconds1 < float(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 (internetTmp == 'true') and (upload_every == 1):
uploadToFTP()
upload_every = upload_only
else:
upload_every -= 1
if upload_every < 0:
upload_every = 0
if upload_every == 0:
logging.info('Skipping upload. Next picture will be uploaded')
print('Skipping upload. Next picture will be uploaded')
else:
logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures')
print('Skipping upload. Next upload in', (upload_every), 'pictures')
checkCpu()
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 internetTmp == '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 internetTmp == 'true': logging.info('uploading todays log befor going to sleep!')
if internetTmp == '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('[FTP] uploaded log-file successful!')
logging.info('[FTP] uploaded log-file successful!')
except Exception as e:
print('[FTP] upload failed!')
print(e)
logging.error('[FTP] 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 Exception as e8:
print('[FTP] re-connecting failed!')
print(e8)
logging.error('[FTP] re-connecting failed!')
logging.error(str(e8))
if reconnectToInternet() == 'true':
print('Reconnect successful')
logging.info('[Internet] Reconnect successful!')
try:
print()
ftp.connect(ftp_url)
ftp.login(ftp_user, ftp_pw)
print('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('[FTP] uploaded log-file successful!')
logging.info('[FTP] uploaded log-file successful!')
except Exception as e4:
print('[FTP] re-connecting failed!')
logging.error('[FTP] re-connecting failed!')
print(str(e4))
logging.error(str(e4))
else:
print('Reconnect failed')
logging.error('[Internet] Reconnect failed!')
try:
ftp.cwd(ftp_picture_directory)
except Exception as er:
print('[FTP] could not change ftp directory !')
logging.error('[FTP] 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 < (
float(wakeup_Time[
datetime.now().month - 1]) * 60 * 60): # if time between 0am and wakeup_Time
sleep_time = (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) - seconds
else: # if time between wakeup_Time and 12pm
sleep_time = 86400 - seconds + (float(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 < (float(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 (internetTmp == 'true') and (upload_every == 1):
uploadToFTP()
upload_every = upload_only
else:
upload_every -= 1
if upload_every < 0:
upload_every = 0
if upload_every == 0:
logging.info('Skipping upload. Next picture will be uploaded')
print('Skipping upload. Next picture will be uploaded')
else:
logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures')
print('Skipping upload. Next upload in', (upload_every), 'pictures')
if internet == 'true' and internetTmp == 'false':
checkConnectionToFTPServer()
checkCpu()
sleepToNextPicture()