def is_light(filename, threshold): """see if the image is not dark""" try: MY_LOGGER.debug('Reading file from URL') data = requests.get(URL_BASE + filename) MY_LOGGER.debug('Writing file') open(WORKING_PATH + filename, 'wb').write(data.content) MY_LOGGER.debug('Reading file') img = cv2.imread(WORKING_PATH + filename) mean_components = img.mean(axis=0).mean(axis=0) mean = (mean_components[0] + mean_components[1] + mean_components[2]) / 3 MY_LOGGER.debug('mean = %f, threshold = %d', mean, threshold) MY_LOGGER.debug('Deleting file') wxcutils.run_cmd('rm ' + WORKING_PATH + filename) if mean > threshold: MY_LOGGER.debug('Light - %f', mean) return True except: MY_LOGGER.critical('is_light exception handler: %s %s %s', sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]) MY_LOGGER.debug('Dark') return False
def process_file(pf_path_filename, pf_source_path, pf_target_path, pf_target_suffix, pf_lock_suffix): """process file, copying it to the correct directory""" MY_LOGGER.debug('process file %s %s %s %s %s', pf_path_filename, pf_source_path, pf_target_path, pf_target_suffix, pf_lock_suffix) pf_filename_lock = pf_path_filename.split(pf_source_path)[1] pf_filename = pf_filename_lock.split(pf_lock_suffix)[0] pf_directory_elements = pf_filename.split('-') MY_LOGGER.debug('filename = %s', pf_filename) # create directory structure make_directories(pf_target_path, pf_directory_elements[0], pf_directory_elements[1], pf_directory_elements[2]) # move file pf_move_to_path = pf_target_path + pf_directory_elements[ 0] + '/' + pf_directory_elements[1] + '/' + pf_directory_elements[ 2] + '/' + pf_target_suffix MY_LOGGER.debug('Moving %s %s to %s %s', pf_source_path, pf_filename + pf_lock_suffix, pf_move_to_path, pf_filename) wxcutils.move_file(pf_source_path, pf_filename + pf_lock_suffix, pf_move_to_path, pf_filename) # remove any existing .html.backup file as this will prevent files being reprocessed # as the existing .html.backup file will be used instead of the new .html file which # will be overwritten if '.html' in pf_filename: if os.path.isfile(pf_move_to_path + '/' + pf_filename + '.backup'): MY_LOGGER.debug('Deleting old .html.backup file') wxcutils.run_cmd('rm ' + pf_move_to_path + '/' + pf_filename + '.backup')
def animate(a_directory, a_filename, a_extenstion, a_frames, a_suffix): """create animation file""" def add_txt(at_path, at_file, add_duration): """add text""" if add_duration: line = 'file \'' + at_path + '/' + at_file + '\'' + \ os.linesep + 'duration 0.05' + os.linesep else: line = 'file \'' + at_path + '/' + at_file + '\'' + os.linesep return line MY_LOGGER.debug( 'directory = %s, filename = %s, extenstion = %s, frames = %d, suffix = %s', a_directory, a_filename, a_extenstion, a_frames, a_suffix) a_files = len(FILES) if a_frames > a_files: a_frames = a_files MY_LOGGER.debug( 'Reduced frames to %d as not enough frames exist (max = %d)', a_frames, a_files) a_text = '' a_original_suffix = a_suffix MY_LOGGER.debug('Going throught the last %d frames', a_frames) if a_suffix != '': a_suffix = '_' + a_suffix + '_web' else: a_suffix = '_web' a_counter = a_files - a_frames while a_counter < a_files: a_text = a_text + add_txt(FILES[a_counter]['dir'], FILES[a_counter]['file'] + \ a_suffix + FILES[a_counter]['ext'], True) a_counter += 1 # add last frame again, but with no duration a_text += add_txt(FILES[a_files - 1]['dir'], FILES[a_files - 1]['file'] + \ a_suffix + FILES[a_files - 1]['ext'], False) # save as a file wxcutils.save_file(WORKING_PATH, 'framelist.txt', a_text) # create animation if a_original_suffix == '': a_suffix = 'raw' else: a_suffix = '_' + a_original_suffix wxcutils.run_cmd('ffmpeg -y -safe 0 -f concat -i ' + WORKING_PATH + 'framelist.txt -c:v libx264 -pix_fmt yuv420p -vf scale=800:800 ' + \ OUTPUT_PATH + 'FD-' + a_suffix + '-' + str(a_frames) + '.mp4') # create file with date time info date_time = 'Last generated at ' + get_local_date_time() + ' ' + \ LOCAL_TIME_ZONE + ' [' + get_utc_date_time() + ' UTC].' wxcutils.save_file(OUTPUT_PATH, 'FD-' + a_suffix + '-' + str(a_frames) + '.txt', date_time)
def process_generated(pg_directory): """process Sanchez files""" MY_LOGGER.debug('---------------------------------------------') sat_dir = BASEDIR + pg_directory MY_LOGGER.debug('Processing %s', pg_directory) MY_LOGGER.debug('sat_dir = %s', sat_dir) # find directories sat_directories = find_directories(sat_dir) for sat_directory in sat_directories: # MY_LOGGER.debug('--') # MY_LOGGER.debug('sat_directory = %s', sat_directory) sat_path = sat_dir + '/' + sat_directory type_directories = find_directories(sat_path) for type_directory in type_directories: # MY_LOGGER.debug('--') # MY_LOGGER.debug('type_directory = %s', type_directory) type_path = sat_path + '/' + type_directory view_directories = find_directories(type_path) for view_directory in view_directories: # MY_LOGGER.debug('--') # MY_LOGGER.debug('view_directory = %s', view_directory) view_path = type_path + '/' + view_directory view_directories = find_directories(view_path) for date_directory in find_directories(view_path): # MY_LOGGER.debug('--') # MY_LOGGER.debug('date_directory = %s', date_directory) date_path = view_path + '/' + date_directory view_directories = find_directories(date_path) for filename in os.listdir(date_path): # date time for the file file_age = TIME_NOW - os.path.getmtime( os.path.join(date_path, filename)) if file_age > MIN_AGE: MY_LOGGER.debug('DELETE - %s %f %f %f', date_path + '/' + filename, file_age, MIN_AGE, MIN_AGE - file_age) wxcutils.run_cmd('rm ' + date_path + '/' + filename) # else: # MY_LOGGER.debug('keep - %s %f %f %f', date_path + '/' + filename, file_age, MIN_AGE, MIN_AGE - file_age) # directory may be empty, if so, remove it if not os.listdir(date_path): MY_LOGGER.debug('deleting empty directory - %s', date_path) wxcutils.run_cmd('rmdir ' + date_path) MY_LOGGER.debug('---------------------------------------------')
def animate(a_frames, a_resolution): """create animation file""" def add_txt(at_path, at_file, add_duration): """add text""" if add_duration: line = 'file \'' + at_path + '/' + at_file + '\'' + os.linesep + 'duration 0.05' + os.linesep else: line = 'file \'' + at_path + '/' + at_file + '\'' + os.linesep return line MY_LOGGER.debug('frames = %d', a_frames) a_files = len(FILES) a_text = '' MY_LOGGER.debug('Going throught the last %d frames', a_frames) a_counter = a_files - a_frames while a_counter < a_files: a_text = a_text + add_txt( FILES[a_counter]['dir'], FILES[a_counter]['file'] + FILES[a_counter]['ext'], True) a_counter += 1 # add last frame again, but with no duration a_text += add_txt(FILES[a_files - 1]['dir'], FILES[a_files - 1]['file'] + FILES[a_files - 1]['ext'], False) # save as a file wxcutils.save_file(WORKING_PATH, 'framelist.txt', a_text) # create animation a_res = str(a_resolution) + ':' + str(a_resolution) a_res_text = str(a_resolution) + 'x' + str(a_resolution) # mobile friendly version a_generate = 'ffmpeg -y -threads ' + str( CORES ) + ' -stream_loop -1 -i ' + AUDIO + ' -safe 0 -f concat -i ' + WORKING_PATH + 'framelist.txt -shortest -c:v libx264 -pix_fmt yuv420p -vf scale=' + a_res + ' ' + OUTPUT_PATH + PREFIX + '-' + str( a_frames) + '-' + a_res_text + '.mp4' MY_LOGGER.debug(a_generate) wxcutils.run_cmd(a_generate) # create file with date time info date_time = 'Last generated at ' + get_local_date_time( ) + ' ' + LOCAL_TIME_ZONE + ' [' + get_utc_date_time() + ' UTC].' wxcutils.save_file(OUTPUT_PATH, PREFIX + '-' + str(a_frames) + '.txt', date_time)
def is_processing(process_name, minutes): """see if images are being created in last defined number of minutes""" cmd = Popen(['find', FILE_BASE + 'goes17', '-cmin', str(-1 * minutes)], stdout=PIPE, stderr=PIPE) stdout, stderr = cmd.communicate() MY_LOGGER.debug('stdout:%s', stdout.decode('utf-8')) MY_LOGGER.debug('stderr:%s', stderr.decode('utf-8')) if len(stdout.decode('utf-8')) > 0: MY_LOGGER.debug('%s is processing images', process_name) return True MY_LOGGER.debug('%s is NOT processing images', process_name) # need to kill off any existing goesproc processes # not totally elegent, but should only be one goesproc on a server wxcutils.run_cmd('pkill -f ' + process_name) return False
def process_goes_2(sat_num): """process GOES xx files - non-standard directory structure""" MY_LOGGER.debug('---------------------------------------------') sat_dir = BASEDIR + 'goes' + sat_num MY_LOGGER.debug('GOES%s', sat_num) MY_LOGGER.debug('sat_dir = %s', sat_dir) # find directories type_directories = find_directories(sat_dir) for type_directory in type_directories: # MY_LOGGER.debug('--') # MY_LOGGER.debug('type_directory = %s', type_directory) channels_directory = os.path.join(sat_dir, type_directory) for date_directory in find_directories(channels_directory): # MY_LOGGER.debug('date_directory = %s', date_directory) for filename in os.listdir(channels_directory + '/' + date_directory): # date time for the file file_age = TIME_NOW - os.path.getmtime( os.path.join(channels_directory + '/' + date_directory, filename)) if file_age > MIN_AGE: MY_LOGGER.debug( 'DELETE - %s %f %f %f', channels_directory + '/' + date_directory + '/' + filename, file_age, MIN_AGE, MIN_AGE - file_age) wxcutils.run_cmd('rm ' + channels_directory + '/' + date_directory + '/' + filename) # else: # MY_LOGGER.debug('keep - %s %f %f %f', channels_directory + '/' + date_directory + '/' + filename, file_age, MIN_AGE, MIN_AGE - file_age) # directory may be empty, if so, remove it if not os.listdir(channels_directory + '/' + date_directory): MY_LOGGER.debug('deleting empty directory - %s', channels_directory + '/' + date_directory) wxcutils.run_cmd('rmdir ' + channels_directory + '/' + date_directory) MY_LOGGER.debug('---------------------------------------------')
def long_check(lc_process): """kill any overly long running processes""" MY_LOGGER.debug('-' * 30) MY_LOGGER.debug('process = %s, max age = %s', lc_process['Process Name'], lc_process['Max Age']) cmd = subprocess.Popen(('ps', '-eo', 'pid,etimes,cmd'), stdout=subprocess.PIPE, stderr=PIPE) stdout, stderr = cmd.communicate() MY_LOGGER.debug('stdout:%s', stdout.decode('utf-8')) MY_LOGGER.debug('stderr:%s', stderr.decode('utf-8')) rows = stdout.decode('utf-8').splitlines() for row in rows: if 'python' in row and lc_process['Process Name'] in row: MY_LOGGER.debug('row = %s', row) bits = row.split() if int(bits[1]) > int(lc_process['Max Age']) * 60: MY_LOGGER.debug('Process too old, need to kill') wxcutils.run_cmd('kill ' + bits[0])
def remove_jobs(match): """remove old AT jobs""" text = subprocess.check_output('atq') lines = text.splitlines() MY_LOGGER.debug('lines = %s', lines) for line in lines: id_value = line.split()[0] MY_LOGGER.debug(' line = %s', line) MY_LOGGER.debug(' id_value = %s', id_value.decode('utf-8')) cmd = Popen(['/usr/bin/at', '-c', id_value.decode('utf-8')], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) stdout, stderr = cmd.communicate() MY_LOGGER.debug('stdout:%s', stdout) MY_LOGGER.debug('stderr:%s', stderr) bits = stdout.split('}') if match in bits[1]: wxcutils.run_cmd('atrm ' + id_value.decode('utf-8'))
def drive_validation(): """validate drive space utilisation""" dv_space = 'unknown' dv_cmd = Popen(['df'], stdout=PIPE, stderr=PIPE) dv_stdout, dv_stderr = dv_cmd.communicate() MY_LOGGER.debug('stdout:%s', dv_stdout) MY_LOGGER.debug('stderr:%s', dv_stderr) dv_results = dv_stdout.decode('utf-8').splitlines() for dv_line in dv_results: if '/dev/root' in dv_line: dv_space = dv_line.split()[4].split('%')[0] MY_LOGGER.debug('dv_space = %s used on %s', dv_space, platform.node()) dv_filename = 'used-' + platform.node() + '.txt' wxcutils.save_file(OUTPUT_PATH, dv_filename, dv_space) # rsync files to server MY_LOGGER.debug('rsync: %s', dv_filename) wxcutils.run_cmd('rsync -t ' + OUTPUT_PATH + dv_filename + ' ' + \ RSYNC_CONFIG['remote user'] + '@' + RSYNC_CONFIG['remote host'] + \ ':' + RSYNC_CONFIG['remote directory'] + '/' + dv_filename)
def backup_servers(): """backup code and config on servers""" # all server code backups are full servers = wxcutils.load_json(CONFIG_PATH, 'servers.json') for server in servers: MY_LOGGER.debug('-' * 40) MY_LOGGER.debug('server = %s', server['server']) for directory in server['directories']: MY_LOGGER.debug('-' * 10) MY_LOGGER.debug(directory['title']) errors.append({ 'type': server['server'] + ' - ' + directory['title'], 'errors': do_rsync('caWv', directory['exclude'], directory['source'], directory['destination']) }) if directory['cmd']: MY_LOGGER.debug('cmd = %s', directory['cmd']) wxcutils.run_cmd('rm -rf ' + directory['cmd']) MY_LOGGER.debug('-' * 40)
def process_nws(): """process nws files""" # note that this code is a work around for an issue with goestools # https://github.com/pietern/goestools/issues/100 # GOES nws directory / filenames are incorrect #100 # once fixed, this code will need to be updated MY_LOGGER.debug('---------------------------------------------') MY_LOGGER.debug('NWS') fixed_dir = BASEDIR + 'nwsdata/' MY_LOGGER.debug('fixed_dir = %s', fixed_dir) for date_directory in find_directories(fixed_dir): # MY_LOGGER.debug('date_directory = %s', date_directory) for filename in os.listdir(fixed_dir + '/' + date_directory): # date time for the file file_age = TIME_NOW - os.path.getmtime( os.path.join(fixed_dir + '/' + date_directory, filename)) if file_age > MIN_AGE: MY_LOGGER.debug( 'DELETE - %s %f %f %f', fixed_dir + '/' + date_directory + '/' + filename, file_age, MIN_AGE, MIN_AGE - file_age) wxcutils.run_cmd('rm ' + fixed_dir + '/' + date_directory + '/' + filename) # else: # MY_LOGGER.debug('keep - %s %f %f %f', fixed_dir + '/' + date_directory + '/' + filename, file_age, MIN_AGE, MIN_AGE - file_age) # directory may be empty, if so, remove it if not os.listdir(fixed_dir + '/' + date_directory): MY_LOGGER.debug('deleting empty directory - %s', fixed_dir + '/' + date_directory) wxcutils.run_cmd('rmdir ' + fixed_dir + '/' + date_directory) MY_LOGGER.debug('---------------------------------------------')
def write_file(): """write TLE""" # update TLE MY_LOGGER.debug('write new TLE to %s', WORKING_PATH + TLE_FILENAME) file_out = open(WORKING_PATH + TLE_FILENAME, 'w+') for satellite in TLE_INFO: MY_LOGGER.debug('%s %s %s', satellite['line_1'], satellite['line_2'], satellite['line_3']) file_out.write(satellite['line_1']) file_out.write(satellite['line_2']) file_out.write(satellite['line_3']) file_out.close() # make sure we got a file created, otherwise re-use the old one if os.path.getsize(WORKING_PATH + TLE_FILENAME) == 0: MY_LOGGER.debug('Issue updating %s file resulting in zero length file', TLE_FILENAME) MY_LOGGER.debug('re-using old one') wxcutils.run_cmd('rm ' + WORKING_PATH + TLE_FILENAME) wxcutils.move_file(WORKING_PATH, TLE_FILENAME + '.old', WORKING_PATH, TLE_FILENAME) else: MY_LOGGER.debug('weather.tle created with non-zero size')
def validate_tle(filename): """validate TLE""" # make sure we got a file created, otherwise re-use the old one file_exists = True file_non_zero_length = True if os.path.exists(WORKING_PATH + filename): MY_LOGGER.debug('File exists - %s', filename) if os.path.getsize(WORKING_PATH + filename) == 0: MY_LOGGER.debug('File is empty - %s', filename) file_non_zero_length = False else: MY_LOGGER.debug('File contains data - %s', filename) else: file_exists = False MY_LOGGER.debug('File does not exist - %s', filename) if not file_exists or not file_non_zero_length: MY_LOGGER.debug('Issue creating / updating %s file', filename) MY_LOGGER.debug('re-using old one (if it exists)') wxcutils.run_cmd('rm ' + WORKING_PATH + filename) wxcutils.move_file(WORKING_PATH, filename + '.old', WORKING_PATH, filename) else: MY_LOGGER.debug('%s validated successfully', filename)
def process_electro_l_2(): """process Electro-L-2 files""" MY_LOGGER.debug('---------------------------------------------') sat_dir = BASEDIR + 'electro-l-2' MY_LOGGER.debug('Electro-L-2') MY_LOGGER.debug('sat_dir = %s', sat_dir) # find directories for date_directory in find_directories(sat_dir): MY_LOGGER.debug('date_directory = %s', date_directory) dates_directory = os.path.join(sat_dir, date_directory) type_directories = find_directories(dates_directory) for type_directory in type_directories: MY_LOGGER.debug('--') MY_LOGGER.debug('type_directory = %s', type_directory) images_directory = os.path.join(dates_directory, type_directory) for filename in os.listdir(images_directory): # date time for the file file_age = TIME_NOW - os.path.getmtime( os.path.join(images_directory, filename)) if file_age > MIN_AGE: MY_LOGGER.debug('DELETE - %s %f %f %f', images_directory + '/' + filename, file_age, MIN_AGE, MIN_AGE - file_age) wxcutils.run_cmd('rm ' + images_directory + '/' + filename) else: MY_LOGGER.debug('keep - %s %f %f %f', images_directory + '/' + filename, file_age, MIN_AGE, MIN_AGE - file_age) # directory may be empty, if so, remove it if not os.listdir(dates_directory + '/' + type_directory): MY_LOGGER.debug('deleting empty directory - %s', dates_directory + '/' + type_directory) wxcutils.run_cmd('rmdir ' + dates_directory + '/' + type_directory) # directory may be empty, if so, remove it if not os.listdir(dates_directory): MY_LOGGER.debug('deleting empty directory - %s', dates_directory) wxcutils.run_cmd('rmdir ' + dates_directory)
for key, value in SATELLITE_INFO.items(): for sat in SATELLITE_INFO[key]: SAT_DATA.append({ 'code': sat['name'].replace(' ', '_').replace('(', '').replace(')', ''), 'name': sat['name'] }) MY_LOGGER.debug('Starting file moving') FILES_MOVED = move_output_files() MY_LOGGER.debug('Finished file moving') if FILES_MOVED: wxcutils.run_cmd('touch ' + TARGET + 'polar.txt') if FILES_MOVED or REBUILD == 'rebuild': MY_LOGGER.debug('Build json passes file') ALL_PASSES = [] build_pass_json() MY_LOGGER.debug('Finished json passes file') MY_LOGGER.debug('Starting capture page building') build_capture_pages() MY_LOGGER.debug('Finished capture page building') elif int(time.strftime('%H')) == 1 and int( time.strftime('%M')) in (0, 1) or REBUILD == 'rebuild': MY_LOGGER.debug('Starting capture page building - overnight run') build_capture_pages() MY_LOGGER.debug('Finished capture page building - overnight run')
def create_branded(satellite): """create branded images""" def add_kiwiweather(): """add kiwiweather""" # Kiwiweather.com nonlocal image image = cv2.putText(image, 'Kiwi', (20, 80), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 255, 255), 2, cv2.LINE_AA) image = cv2.putText(image, 'Weather', (20, 160), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 255, 255), 2, cv2.LINE_AA) image = cv2.putText(image, '.com', (20, 240), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 255, 255), 2, cv2.LINE_AA) image = cv2.putText(image, 'ZL4MDE', (20, 320), cv2.FONT_HERSHEY_SIMPLEX, 2, (255, 255, 255), 2, cv2.LINE_AA) def add_logo(x_offset): """add logo""" # logo y_offset = 0 nonlocal image image[y_offset:y_offset + logo.shape[0], x_offset:x_offset + logo.shape[1]] = logo def add_date(y_offset): """add date and time""" # date / time info bits = file['file'].split('_') year = bits[4][:4] month = calendar.month_abbr[int(bits[4][4:6])] day = bits[4][6:8] hour = bits[5][:2] min = bits[5][2:4] # MY_LOGGER.debug('year = %s, month = %s, day = %s, # hour = %s min = %s', year, month, day, hour, min) nonlocal image image = cv2.putText(image, hour + ':' + min + ' UTC', (20, y_offset), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 255, 255), 2, cv2.LINE_AA) image = cv2.putText(image, day + '-' + month + '-' + year, (20, 80 + y_offset), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 255, 255), 2, cv2.LINE_AA) def add_sat_info(x_offset, y_offset, satellite, process): """add satellite info""" nonlocal image image = cv2.putText(image, satellite, (x_offset, y_offset), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 255, 255), 2, cv2.LINE_AA) image = cv2.putText(image, process, (x_offset, 80 + y_offset), cv2.FONT_HERSHEY_SIMPLEX, 3, (255, 255, 255), 2, cv2.LINE_AA) MY_LOGGER.debug('create branded images where required') # load logo MY_LOGGER.debug('load logo') logo = cv2.imread(CONFIG_PATH + 'logo.jpg') images_created = 0 for file in FILES: # MY_LOGGER.debug('file = %s', file) # does raw branded file exist? if not os.path.exists(file['dir'] + '/' + file['file'] + '_web' + file['ext']): images_created += 1 MY_LOGGER.debug('creating raw branded') # load raw image image = cv2.imread(file['dir'] + '/' + file['file'] + file['ext']) add_kiwiweather() add_logo(2000) add_date(2100) add_sat_info(1700, 2100, satellite, 'IR') # write out image cv2.imwrite( file['dir'] + '/' + file['file'] + '_web' + file['ext'], image) # else: # MY_LOGGER.debug('raw branded exists') # does sanchez file exist? if not os.path.exists(file['dir'] + '/' + file['file'] + '_sanchez' + file['ext']): images_created += 1 MY_LOGGER.debug('creating sanchez') wxcutils.run_cmd('/home/pi/sanchez/Sanchez -u ' + CONFIG_PATH + 'world.2004' + \ str(datetime.now().month).zfill(2) + '.3x5400x2700.jpg -s ' + file['dir'] + '/' + file['file'] + \ file['ext'] + ' -o ' + file['dir'] + '/' + file['file'] + \ '_sanchez' + file['ext']) # else: # MY_LOGGER.debug('sanchez exists') # does sanchez branded file exist? if not os.path.exists(file['dir'] + '/' + file['file'] + '_sanchez_web' + file['ext']): images_created += 1 MY_LOGGER.debug('creating raw branded') # load raw image image = cv2.imread(file['dir'] + '/' + file['file'] + '_sanchez' + file['ext']) add_kiwiweather() add_logo(2512) add_date(2612) add_sat_info(2100, 2612, 'GK-2A', 'IR Sanchez') # write out image cv2.imwrite( file['dir'] + '/' + file['file'] + '_sanchez_web' + file['ext'], image) # else: # MY_LOGGER.debug('raw branded exists') # does clahe branded file exist? if not os.path.exists(file['dir'] + '/' + file['file'] + '_clahe_web' + file['ext']): images_created += 1 MY_LOGGER.debug('creating clahe branded') clahe_process(file['dir'] + '/', file['file'] + file['ext'], WORKING_PATH, 'clahe.jpg') # load raw image image = cv2.imread(WORKING_PATH + 'clahe.jpg') add_kiwiweather() add_logo(2000) add_date(2100) add_sat_info(1700, 2100, 'GK-2A', 'IR Clahe') # write out image cv2.imwrite( file['dir'] + '/' + file['file'] + '_clahe_web' + file['ext'], image) # else: # MY_LOGGER.debug('raw branded exists') MY_LOGGER.debug('Images created = %d', images_created) if images_created > 0: return True return False
def create_thumbnail(ct_directory, ct_extension): """create thumbnail of the image""" wxcutils.run_cmd('convert \"' + OUTPUT_PATH + ct_directory + ct_extension + '\" -resize 9999x500 ' + OUTPUT_PATH + ct_directory + '-tn' + ct_extension)
def proccess_satellite(sat_info): """process satellite info from web""" # set up variables file_directory = FILE_BASE + sat_info['File base'] MY_LOGGER.debug('Satellite = %s', sat_info['Name']) MY_LOGGER.debug('file_directory = %s', file_directory) MY_LOGGER.debug('last directory = %s', sat_info['Last Directory']) MY_LOGGER.debug('URL = %s', sat_info['URL']) directories = sorted(listFD(sat_info['URL'], '')) # loop through directories for directory in directories: MY_LOGGER.debug('directory = %s', directory) directory_datetime = directory.split('/')[5] MY_LOGGER.debug('directory_datetime = %s', directory_datetime) # skip where getting a website (Cloudflare) if directory_datetime == 'https:': MY_LOGGER.debug('Skipping invalid directory %s', directory_datetime) else: if directory_datetime >= sat_info['Last Directory']: MY_LOGGER.debug('-' * 5) MY_LOGGER.debug('Need to process %s', directory_datetime) elements = directory_datetime.split('_') date_element = elements[0] MY_LOGGER.debug('date_element = %s', date_element) image_files = listFD(directory, 'png') channel_locator = len(sat_info['File in prefix']) + 1 MY_LOGGER.debug('channel_locator = %s', channel_locator) # create directories MY_LOGGER.debug('file_directory = %s', file_directory) mk_dir(file_directory + '/' + date_element) mk_dir(file_directory + '/' + date_element + '/1') mk_dir(file_directory + '/' + date_element + '/2') mk_dir(file_directory + '/' + date_element + '/3') mk_dir(file_directory + '/' + date_element + '/4') mk_dir(file_directory + '/' + date_element + '/5') mk_dir(file_directory + '/' + date_element + '/FC') # make directory for web files (goes13 only) if sat_info['Name'] == 'GOES 13': mk_dir(WEB_PATH + '/goes13/fd/1/' + date_element) mk_dir(WEB_PATH + '/goes13/fd/2/' + date_element) mk_dir(WEB_PATH + '/goes13/fd/3/' + date_element) mk_dir(WEB_PATH + '/goes13/fd/4/' + date_element) mk_dir(WEB_PATH + '/goes13/fd/5/' + date_element) mk_dir(WEB_PATH + '/goes13/fd/FC/' + date_element) existsCount = 0 for file in image_files: filename = file.split('/')[-1] if sat_info['File in prefix'] in filename: MY_LOGGER.debug('filename = %s', filename) channel = '?' if filename[channel_locator] == 'F': file_location = file_directory + '/' + date_element + '/FC/' channel = 'FC' else: file_location = file_directory + '/' + date_element + '/' + filename[ channel_locator] + '/' channel = filename[channel_locator] MY_LOGGER.debug('file_location = %s', file_location) MY_LOGGER.debug('channel = %s', channel) # see if file exists, if not, get it if not os.path.exists( file_location + filename.replace('.png', '.jpg')): # get file MY_LOGGER.debug('Getting file %s', filename) data = requests.get(file) MY_LOGGER.debug('Writing file %s', filename) open(file_location + filename, 'wb').write(data.content) # non-channel 1 and FC images are ~5k x 5k pixels # channel 1 and FC images are 20832 x 18956 ~190MB each # convert all to jpg images, aligned with GOES images size, which are 5424x5424 # keeping the correct aspect ratio so 5424 x 4936 if channel not in ('1', 'FC'): ratio = ' 1' else: ratio = ' 0.2604' cmd = 'vips resize ' + file_location + filename + ' ' + file_location + filename.replace( '.png', '.jpg') + ratio MY_LOGGER.debug('cmd %s', cmd) wxcutils.run_cmd(cmd) # can now delete the original image to save space wxcutils.run_cmd('rm ' + file_location + filename) if sat_info['Name'] == 'GOES 13': bits = filename.split('_') for bit in bits: MY_LOGGER.debug('bit %s', bit) year = bits[-1][:4] month = calendar.month_abbr[int(bits[-1][4:6])] day = bits[-1][6:8] hour = bits[-1][9:11] min = bits[-1][11:13] MY_LOGGER.debug( 'year = %s, month = %s, day = %s, hour = %s min = %s', year, month, day, hour, min) im_date = day + '-' + month + '-' + year im_time = hour + ':' + min + ' UTC' MY_LOGGER.debug( 'Creating branded image - %s, date %s, time %s', channel, im_date, im_time) web_file = create_branded( 'goes', '13', 'fd', channel, file_location, filename.replace('.png', ''), '.jpg', im_date, im_time) # copy to output directory new_filename = 'goes13-' + channel + '.jpg' MY_LOGGER.debug('new_filename = %s', new_filename) wxcutils.copy_file( web_file, os.path.join(OUTPUT_PATH, new_filename)) else: # non-GOES 13 # copy file to output folder wxcutils.copy_file( file_location + filename.replace('.png', '.jpg'), OUTPUT_PATH + sat_info['File out prefix'] + '-' + channel + '.jpg') # create thumbnail and txt file cmd = 'vips resize ' + OUTPUT_PATH + sat_info[ 'File out prefix'] + '-' + channel + '.jpg' + ' ' + OUTPUT_PATH + sat_info[ 'File out prefix'] + '-' + channel + '-tn.jpg' + ' 0.1' MY_LOGGER.debug('cmd %s', cmd) wxcutils.run_cmd(cmd) # create file with date time info MY_LOGGER.debug( 'Writing out last generated date file') wxcutils.save_file( OUTPUT_PATH, sat_info['File out prefix'] + '-' + channel + '.txt', get_last_generated_text( filename.replace('.png', '.jpg'))) else: MY_LOGGER.debug('Already exists %s', file_location + filename) existsCount += 1 # check age of directory to skip over "OLD" directories # 2021-08-11_16-56 directory_datetime_dt = datetime.datetime.strptime( directory_datetime, '%Y-%m-%d_%H-%M') directory_datetime_epoch = wxcutils.utc_datetime_to_epoch( directory_datetime_dt) current_epoch = time.time() directory_age = current_epoch - float( directory_datetime_epoch) MY_LOGGER.debug('current_epoch = %f', current_epoch) MY_LOGGER.debug('directory_datetime_epoch = %f', float(directory_datetime_epoch)) MY_LOGGER.debug('age = %f', directory_age) if existsCount == 6 or directory_age > (6 * 60 * 60): if existsCount == 6: MY_LOGGER.debug( 'all 6 files exist - update last directory') else: MY_LOGGER.debug( 'Directory age is too old, assuming files will not appear - 6 hours' ) if directory_datetime > sat_info['Last Directory']: MY_LOGGER.debug( 'Old last directory = %s, new last directory = %s', sat_info['Last Directory'], directory_datetime) sat_info['Last Directory'] = directory_datetime else: MY_LOGGER.debug( 'No change required - Old last directory = %s, new last directory = %s', sat_info['Last Directory'], directory_datetime)
IMAGE_OPTIONS, str(MAX_ELEVATION)) # capture pass to wav file # timeout 600 rtl_fm -M raw -f 137.9M -s 130k -g 8 -p 0 | # sox -t raw -r 130k -c 2 -b 16 -e s - -t wav "meteor_a.wav" rate 96k if REPROCESS != 'Y': BIAS_T = get_bias_t() # Sleep until the required start time # to account for at scheduler starting up to 59 seconds early wxcutils_pi.sleep_until_start(float(START_EPOCH)) MY_LOGGER.debug('Starting audio capture') wxcutils.run_cmd( 'timeout ' + DURATION + ' rtl_fm -d ' + str(WX_SDR) + BIAS_T + ' -M raw -f ' + str(PASS_INFO['frequency']) + 'M -s 130k ' + GAIN_COMMAND + ' -p 0 | sox -t raw -r 130k -c 2 -b 16 -e s - -t wav \"' + AUDIO_PATH + FILENAME_BASE + '.wav\" rate 96k') if os.path.isfile(AUDIO_PATH + FILENAME_BASE + '.wav'): MY_LOGGER.debug('Audio file created') else: MY_LOGGER.debug('Audio file NOT created') else: MY_LOGGER.debug('Reprocessing original .wav file') MY_LOGGER.debug('-' * 30) # assume we don't get a valid page, but confirm if we do CREATE_PAGE = False # Demodulate .wav to QPSK
create_thumbnail(directory, extenstion) # create file with date time info if directory != 'ANT': wxcutils.save_file(OUTPUT_PATH, directory + '.txt', date_time) else: wxcutils.save_file(OUTPUT_PATH, 'ANT.txt.txt', date_time) else: MY_LOGGER.debug('File unchanged') # save latest times data wxcutils.save_json(OUTPUT_PATH, 'gk2a_info.json', latest_timestamps) # rsync files to servers wxcutils.run_cmd('rsync -rtPv ' + OUTPUT_PATH + ' [email protected]:/home/mike/wxcapture/gk-2a') wxcutils.run_cmd( 'rsync -rtPv ' + base_dir + ' --exclude *_sanchez* --exclude *web* [email protected]:/home/pi/goes/gk-2a' ) else: MY_LOGGER.debug('Another instance of find_files.py is already running') MY_LOGGER.debug( 'Skip running this instance to allow the existing one to complete') # except: # MY_LOGGER.critical('Global exception handler: %s %s %s', # sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]) MY_LOGGER.debug('Execution end')
for nc in NETCONFIG[key]: if nc['Active'] == 'yes': MY_LOGGER.debug('-' * 20) MY_LOGGER.debug(nc) # need to fix updating the NETCONFIG part! nc['status'] = test_connection(nc, NETCONFIG['attempt'], NETCONFIG['timeout']) nc['when'] = time.time() wxcutils.save_json(OUTPUT_PATH, 'network.json', NETCONFIG) # test if goesproc is running or processing if not is_running('goesproc') or not is_processing('goesproc', 10): # need to kick off the code MY_LOGGER.debug('Kicking it off') wxcutils.run_cmd( 'goesproc -c /usr/share/goestools/goesproc-goesr.conf -m packet ' + '--subscribe tcp://203.86.195.49:5004 --out /home/pi/goes &') if is_running('goesproc'): MY_LOGGER.debug('goesproc is now running') else: MY_LOGGER.critical( 'goesproc is NOT running and could not be restarted') # log drive space free to file drive_validation() # test if tweet.py is running, if not kick it off MY_LOGGER.debug('=' * 20) if not is_running('tweet.py'): # need to kick off the code MY_LOGGER.debug('tweet.py not running - kicking it off')
REBOOT = True # see if too many find_files.py are running if number_processes('find_files.py') > 1: MY_LOGGER.debug('Too many find_files.py running') REBOOT = True # log drive space free to file drive_validation() # validate satellite info sat_validation() # sync the output files wxcutils.run_cmd( 'rsync -rtPv ' + OUTPUT_PATH + 'used-gamma.txt [email protected]:/home/mike/wxcapture/gk-2a') wxcutils.run_cmd( 'rsync -rtPv ' + OUTPUT_PATH + 'satellite-receivers.json [email protected]:/home/mike/wxcapture/gk-2a') if REBOOT: # reboot the Pi MY_LOGGER.debug('rebooting the Pi') wxcutils.run_cmd('reboot') else: # All good, no action required MY_LOGGER.debug('All good, no action required') MY_LOGGER.debug('Execution end') MY_LOGGER.debug('-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+')
# newline definition NEWLINE = os.linesep + os.linesep # get the run time, to use for email date time ALERT_INFO = get_local_date_time() + ' ' + LOCAL_TIME_ZONE + \ ' [' + get_utc_date_time() + ' UTC].' MY_LOGGER.debug('ALERT_INFO = %s', ALERT_INFO) MY_LOGGER.debug('-' * 20) # try to send email to main server MY_LOGGER.debug('Trying main email server') if not send_email('email.json', 'Main server test'): MY_LOGGER.error('Error with main server, restart postfix and dovecot') MY_LOGGER.debug('Restart postfix') wxcutils.run_cmd('postfix stop') wxcutils.run_cmd('postfix start') MY_LOGGER.debug('Restart dovecot') wxcutils.run_cmd('systemctl stop dovecot') wxcutils.run_cmd('systemctl start dovecot') MY_LOGGER.debug('Sleeping 10 sec to allow servers to restart') time.sleep(10) MY_LOGGER.debug('Trying main email server post restarts') if not send_email('email.json', 'Main server test'): MY_LOGGER.error('Error with main server, need to reboot') # notify issue via alternate email server if not send_email('email2.json', 'Alternate server email - main server REBOOT'): MY_LOGGER.debug('Sending Email using alternate server also failed') else: MY_LOGGER.debug('Sending Email using alternate server worked') MY_LOGGER.debug('Rebooting server')
MY_LOGGER.debug('DATE_TIME_PARAM = %s', DATE_TIME_PARAM) except IndexError as exc: MY_LOGGER.critical( 'Exception whilst parsing command line parameters: %s %s %s', sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]) # re-throw it as this is fatal raise date_directory = DATE_TIME_PARAM.split('T')[0] MY_LOGGER.debug('date_directory = %s', date_directory) # copy GOES 16 files to the directory wxcutils.run_cmd('cp -r ' + SOURCE_DIR_PARAM + '/goes16/fd/ch13/*' + date_directory + ' ' + WORKING_PATH) # copy GOES 17 files to the directory wxcutils.run_cmd('cp -r ' + SOURCE_DIR_PARAM + '/goes17/fd/ch13/*' + date_directory + ' ' + WORKING_PATH) # copy GK-2A files to the directory gk_2a_year = date_directory[0:4] MY_LOGGER.debug('gk_2a_year = %s', gk_2a_year) wxcutils.run_cmd('cp ' + SOURCE_DIR_PARAM + 'gk-2a/' + gk_2a_year + '/' + date_directory.replace('-', '') + '/FD/* ' + WORKING_PATH + date_directory) # run sanchez cmd = Popen([ '/home/mike/sanchez/Sanchez', 'reproject', '-s', WORKING_PATH +
filename, extenstion = os.path.splitext(latest_file) MY_LOGGER.debug('extenstion = %s', extenstion) # date time for original file latest = os.path.getmtime(os.path.join(location, latest_file)) MY_LOGGER.debug('latest = %d', latest) latest_local = wxcutils.epoch_to_local(latest, '%a %d %b %H:%M') MY_LOGGER.debug('latest_local = %s', latest_local) # crawl directories for all files crawl_images(directory) # sort FILES = sorted(FILES, key=lambda k: k['datetime']) num_files = len(FILES) MY_LOGGER.debug('num_files = %s', num_files) # save to file system for debugging only # wxcutils.save_json(WORKING_PATH, 'crawl.json', FILES) # animate(directory, filename, extenstion, 143 * 10, '', 2200) # animate(directory, filename, extenstion, 143 * 10, 'sanchez', 2200) animate(directory, filename, extenstion, num_files, '', 2200) animate(directory, filename, extenstion, num_files, 'sanchez', 2200) wxcutils.run_cmd('mv ' + OUTPUT_PATH + '* /mnt/g/weather/GK-2A') # except: # MY_LOGGER.critical('Global exception handler: %s %s %s', # sys.exc_info()[0], sys.exc_info()[1], sys.exc_info()[2]) MY_LOGGER.debug('Execution end') MY_LOGGER.debug('-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+')
def move_output_files(): """move the files from the output directories to the correct locations""" # scan for any non-unlock files MY_LOGGER.debug('Non-unlock files') # move satstatus.csv mof_file = 'satstatus.csv' if os.path.isfile(MY_PATH + mof_file): MY_LOGGER.debug('Processing %s', mof_file) wxcutils.move_file(MY_PATH, mof_file, TARGET, mof_file) MY_LOGGER.debug('zipping%s', mof_file) wxcutils.run_cmd('zip ' + TARGET + mof_file + '.zip ' + TARGET + mof_file) MY_LOGGER.debug('removing %s', mof_file) wxcutils.run_cmd('rm ' + TARGET + mof_file) else: MY_LOGGER.debug('No %s to copy', mof_file) # move serverstatus.csv mof_file = 'serverstatus.csv' if os.path.isfile(MY_PATH + mof_file): MY_LOGGER.debug('Processing %s', mof_file) wxcutils.move_file(MY_PATH, mof_file, TARGET, mof_file) MY_LOGGER.debug('zipping%s', mof_file) wxcutils.run_cmd('zip ' + TARGET + mof_file + '.zip ' + TARGET + mof_file) MY_LOGGER.debug('removing %s', mof_file) wxcutils.run_cmd('rm ' + TARGET + mof_file) else: MY_LOGGER.debug('No %s to copy', mof_file) # move used-*.txt.csv MY_LOGGER.debug('Moving used-*.txt') wxcutils.run_cmd('mv ' + MY_PATH + 'used-*.txt ' + TARGET) # scan for any unlock files MY_LOGGER.debug('Unlock files') files_moved = False for unlock_file in glob.glob(MY_PATH + '*.UNLOCK'): files_moved = True unlock_path, unlock_filename = os.path.split(unlock_file) lock_number = unlock_filename.split('.')[0] lock_suffix = '.LOCK.' + lock_number MY_LOGGER.debug('Unlock file for %s %s - lock # %s lock suffix %s', unlock_path, unlock_filename, lock_number, lock_suffix) # move satpass.html if os.path.isfile(MY_PATH + 'satpass.html' + lock_suffix): MY_LOGGER.debug('Processing satpass.html') wxcutils.move_file(MY_PATH, 'satpass.html' + lock_suffix, TARGET, 'satpass.html') else: MY_LOGGER.debug('No satpass.html to copy') # move satellitestatus.html if os.path.isfile(MY_PATH + 'satellitestatus.html' + lock_suffix): MY_LOGGER.debug('Processing satellitestatus.html') wxcutils.move_file(MY_PATH, 'satellitestatus.html' + lock_suffix, TARGET, 'satellitestatus.html') else: MY_LOGGER.debug('No satellitestatus.html to copy') # move config.html if os.path.isfile(MY_PATH + 'config.html' + lock_suffix): MY_LOGGER.debug('Processing config.html') wxcutils.move_file(MY_PATH, 'config.html' + lock_suffix, TARGET, 'config.html') else: MY_LOGGER.debug('No config.html to copy') # find images in the images folder and move them # will include plots, maps and sat images # .png and .jpg extensions MY_LOGGER.debug('Image search = %s', MY_PATH + 'images/*' + lock_suffix) for image_file in glob.glob(MY_PATH + 'images/*' + lock_suffix): MY_LOGGER.debug('Image file = %s', image_file) process_file(image_file, MY_PATH + 'images/', TARGET, 'images/', lock_suffix) # find audio files in the audio folder and move them # should be just .wav files MY_LOGGER.debug('Audio search = %s', MY_PATH + 'audio/*' + lock_suffix) for audio_file in glob.glob(MY_PATH + 'audio/*' + lock_suffix): MY_LOGGER.debug('Audio file = %s', audio_file) process_file(audio_file, MY_PATH + 'audio/', TARGET, 'audio/', lock_suffix) # find .tle files in the output folder and move them MY_LOGGER.debug('.tle search = %s', MY_PATH + '*.tle' + lock_suffix) for tle_file in glob.glob(MY_PATH + '*.tle' + lock_suffix): MY_LOGGER.debug('.tle file = %s', tle_file) process_file(tle_file, MY_PATH, TARGET, '', lock_suffix) # find .json files in the output folder and move them MY_LOGGER.debug('.json search = %s', MY_PATH + '*.json' + lock_suffix) for json_file in glob.glob(MY_PATH + '*.json' + lock_suffix): MY_LOGGER.debug('.json file = %s', json_file) process_file(json_file, MY_PATH, TARGET, '', lock_suffix) # find .txt files in the output folder and move them MY_LOGGER.debug('.txt search = %s', MY_PATH + '*.txt' + lock_suffix) for txt_file in glob.glob(MY_PATH + '*.txt' + lock_suffix): MY_LOGGER.debug('.txt file = %s', txt_file) process_file(txt_file, MY_PATH, TARGET, '', lock_suffix) # find .dec files in the output folder and move them MY_LOGGER.debug('.dec search = %s', MY_PATH + '*.dec' + lock_suffix) for dec_file in glob.glob(MY_PATH + '*.dec' + lock_suffix): MY_LOGGER.debug('.dec file = %s', dec_file) process_file(dec_file, MY_PATH, TARGET, '', lock_suffix) # get a list of the pass html files for fixing pass_files = [ f for f in listdir(MY_PATH) if isfile(join(MY_PATH, f)) and '.UNLOCK' not in f ] MY_LOGGER.debug('________________%s', pass_files) # find .html files in the output folder and move them MY_LOGGER.debug('.html search = %s', MY_PATH + '*.html' + lock_suffix) for htm_file in glob.glob(MY_PATH + '*.html' + lock_suffix): MY_LOGGER.debug('.html file = %s', htm_file) process_file(htm_file, MY_PATH, TARGET, '', lock_suffix) # copying done for this lock, so remove unlock file wxcutils.run_cmd('rm ' + unlock_file) # apply the modal windows fix for all new pass html files MY_LOGGER.debug('Modal move check') MY_LOGGER.debug(pass_files) for file_name in pass_files: if 'config.html' not in file_name and 'satpass.html' not in file_name and 'meteor_index.html' not in file_name and 'noaa_index.html' not in file_name and 'satellitestatus' not in file_name: MY_LOGGER.debug( 'Applying modal fixes to pass files just copied') MY_LOGGER.debug('file_name = %s', file_name.split('.LOCK.')[0]) file_bits = file_name.split('.LOCK.')[0].split('-') location = TARGET + file_bits[0] + '/' + file_bits[ 1] + '/' + file_bits[2] + '/' if '.html' in file_name: MY_LOGGER.debug('fix file %s %s', location, file_name.split('.LOCK.')[0]) fix_pass_pages_lib.fix_file(location, file_name.split('.LOCK.')[0]) return files_moved
def animate(a_directory, a_filename, a_extenstion, a_frames, a_suffix, a_resolution): """create animation file""" def add_txt(at_path, at_file, add_duration): """add text""" if add_duration: line = 'file \'' + at_path + '/' + at_file + '\'' + os.linesep + 'duration 0.05' + os.linesep else: line = 'file \'' + at_path + '/' + at_file + '\'' + os.linesep return line MY_LOGGER.debug( 'directory = %s, filename = %s, extenstion = %s, frames = %d, suffix = %s', a_directory, a_filename, a_extenstion, a_frames, a_suffix) a_files = len(FILES) if a_frames > a_files: a_frames = a_files MY_LOGGER.debug( 'Reduced frames to %d as not enough frames exist (max = %d)', a_frames, a_files) a_text = '' MY_LOGGER.debug('Going throught the last %d frames', a_frames) if a_suffix != '': a_suffix = '_' + a_suffix a_counter = a_files - a_frames while a_counter < a_files: a_text = a_text + add_txt( FILES[a_counter]['dir'], FILES[a_counter]['file'] + a_suffix + FILES[a_counter]['ext'], True) if not os.path.exists(FILES[a_counter]['dir'] + '/' + FILES[a_counter]['file'] + a_suffix + FILES[a_counter]['ext']): # need to generate file if a_suffix == '_sanchez': MY_LOGGER.debug('sanchez file to create') MY_LOGGER.debug( '/home/mike/sanchez/Sanchez -s ' + FILES[a_counter]['dir'] + '/' + FILES[a_counter]['file'] + FILES[a_counter]['ext'] + ' -m /home/mike/sanchez/Resources/Mask.jpg -u /home/mike/sanchez/Resources/GK-2A/Underlay.jpg -o ' + FILES[a_counter]['dir'] + '/' + FILES[a_counter]['file'] + a_suffix + FILES[a_counter]['ext'] + ' -t 0070BA') wxcutils.run_cmd( '/home/mike/sanchez/Sanchez -s ' + FILES[a_counter]['dir'] + '/' + FILES[a_counter]['file'] + FILES[a_counter]['ext'] + ' -m /home/mike/sanchez/Resources/Mask.jpg -u /home/mike/sanchez/Resources/GK-2A/Underlay.jpg -o ' + FILES[a_counter]['dir'] + '/' + FILES[a_counter]['file'] + a_suffix + FILES[a_counter]['ext'] + ' -t 0070BA') else: MY_LOGGER.debug('%s file to create', a_suffix) a_counter += 1 # add last frame again, but with no duration a_text += add_txt( FILES[a_files - 1]['dir'], FILES[a_files - 1]['file'] + a_suffix + FILES[a_files - 1]['ext'], False) # save as a file wxcutils.save_file(WORKING_PATH, 'framelist.txt', a_text) # create animation if a_suffix == '': a_suffix = 'raw' a_res = str(a_resolution) + ':' + str(a_resolution) a_res_text = str(a_resolution) + 'x' + str(a_resolution) a_generate = 'ffmpeg -y -safe 0 -threads ' + str( CORES ) + ' -f concat -i ' + WORKING_PATH + 'framelist.txt -c:v libx264 -pix_fmt yuv420p -vf scale=' + a_res + ' ' + OUTPUT_PATH + 'FD-' + a_suffix + '-' + str( a_frames) + '-' + a_res_text + '.mp4' MY_LOGGER.debug(a_generate) wxcutils.run_cmd(a_generate) # create file with date time info date_time = 'Last generated at ' + get_local_date_time( ) + ' ' + LOCAL_TIME_ZONE + ' [' + get_utc_date_time() + ' UTC].' wxcutils.save_file(OUTPUT_PATH, 'FD-' + a_suffix + '-' + str(a_frames) + '.txt', date_time)
GAIN_COMMAND, GAIN_DESCRIPTION, GAIN_VALUE = wxcutils_pi.get_gain( IMAGE_OPTIONS, str(MAX_ELEVATION)) # capture pass to wav file if REPROCESS != 'Y': BIAS_T = get_bias_t() # Sleep until the required start time # to account for at scheduler starting up to 59 seconds early wxcutils_pi.sleep_until_start(float(START_EPOCH)) MY_LOGGER.debug('Starting audio capture') wxcutils.run_cmd( 'timeout ' + DURATION + ' rtl_fm -d ' + str(WX_SDR) + BIAS_T + ' -M fm -f ' + str(PASS_INFO['frequency']) + 'M -s 48k ' + GAIN_COMMAND + ' -p 0 | sox -t raw -r 48k -c 1 -b 16 -e s - -t wav \"' + AUDIO_PATH + FILENAME_BASE + '.wav\" rate 48k') MY_LOGGER.debug('Finished audio capture') if os.path.isfile(AUDIO_PATH + FILENAME_BASE + '.wav'): MY_LOGGER.debug('Audio file created') else: MY_LOGGER.debug('Audio file NOT created') else: MY_LOGGER.debug('Reprocessing original .wav file') MY_LOGGER.debug('-' * 30) # need to ensure that the following are running: # * pactl load-module module-null-sink sink_name=virtual-cable # * qsstv
GAIN_COMMAND, GAIN_DESCRIPTION, GAIN_VALUE = wxcutils_pi.get_gain( IMAGE_OPTIONS, str(MAX_ELEVATION)) # capture pass to wav file if REPROCESS != 'Y': BIAS_T = get_bias_t() # Sleep until the required start time # to account for at scheduler starting up to 59 seconds early wxcutils_pi.sleep_until_start(float(START_EPOCH)) MY_LOGGER.debug('Starting audio capture') wxcutils.run_cmd( 'timeout ' + DURATION + ' rtl_fm -d ' + str(WX_SDR) + BIAS_T + ' -M wbfm -f ' + str(PASS_INFO['frequency']) + 'M -s 200k -r 48k ' + GAIN_COMMAND + ' -p 0 | sox -t raw -r 48k -c 1 -b 16 -e s - -t wav \"' + AUDIO_PATH + FILENAME_BASE + '.wav\" rate 48k') if os.path.isfile(AUDIO_PATH + FILENAME_BASE + '.wav'): MY_LOGGER.debug('Audio file created') else: MY_LOGGER.debug('Audio file NOT created') else: MY_LOGGER.debug('Reprocessing original .wav file') MY_LOGGER.debug('-' * 30) # parse the audio using multimon-ng MY_LOGGER.debug('Starting decode') # sox -t wav morse_sample.wav -esigned-integer -b16 -r 22050 -t raw morse_sample.raw # may not need!