def rmsExternal(captured_night_dir, archived_night_dir, config): # Compute the capture duration from now start_time, duration = captureDuration(config.latitude, config.longitude, config.elevation) timenow = datetime.datetime.utcnow() remaining_seconds = 0 # Compute how long to wait before capture if start_time != True: waitingtime = start_time - timenow remaining_seconds = int(waitingtime.total_seconds()) # Run the Istrastream shell script script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "iStream.sh") os.system(script_path + " {:s} {:s} {:s} {:.6f} {:.6f} {:.1f} {:d} {:d} {:d}".format(config.stationID, \ captured_night_dir, archived_night_dir, config.latitude, config.longitude, config.elevation, \ config.width, config.height, remaining_seconds))
nodetect=cml_args.nodetect) upload_manager = None if config.upload_enabled: # Init the upload manager log.info('Starting the upload manager...') upload_manager = UploadManager(config) upload_manager.start() # Automatic running and stopping the capture at sunrise and sunset while True: # Calculate when and how should the capture run start_time, duration = captureDuration(config.latitude, config.longitude, config.elevation) log.info('Next start time: ' + str(start_time) + ' UTC') # Don't start the capture if there's less than 15 minutes left if duration < 15 * 60: log.debug( 'Less than 15 minues left to record, waiting new recording session...' ) # Reset the Ctrl+C to KeyboardInterrupt resetSIGINT() try:
def deleteOldObservations(data_dir, captured_dir, archived_dir, config, duration=None): """ Deletes old observation directories to free up space for new ones. Arguments: data_dir: [str] Path to the RMS data directory which contains the Captured and Archived diretories captured_dir: [str] Captured directory name. archived_dir: [str] Archived directory name. config: [Configuration object] Keyword arguments: duration: [float] Duration of next video capturing in seconds. If None (by default), duration will be calculated for the next night. Return: [bool]: True if there's enough space for the next night's data, False if not. """ captured_dir = os.path.join(data_dir, captured_dir) archived_dir = os.path.join(data_dir, archived_dir) ### Calculate the approximate needed disk space for the next night # If the duration of capture is not given if duration is None: # Time of next local noon #ct = datetime.datetime.utcnow() #noon_time = datetime.datetime(ct.year, ct.month, ct.date, 12) # Initialize the observer and find the time of next noon o = ephem.Observer() o.lat = config.latitude o.long = config.longitude o.elevation = config.elevation sun = ephem.Sun() sunrise = o.previous_rising(sun, start=ephem.now()) noon_time = o.next_transit(sun, start=sunrise).datetime() # if ct.hour > 12: # noon_time += datetime.timedelta(days=1) # Get the duration of the next night _, duration = captureDuration(config.latitude, config.longitude, config.elevation, current_time=noon_time) # Calculate the approx. size for the night night next_night_bytes = (duration*config.fps)/256*config.width*config.height*4 # Always leave at least 2 GB free for archive next_night_bytes += config.extra_space_gb*(1024**3) ###### log.info("Need {:.2f} GB for next night".format(next_night_bytes/1024/1024/1024)) # If there's enough free space, don't do anything if availableSpace(data_dir) > next_night_bytes: return True # Intermittently delete captured and archived directories until there's enough free space prev_available_space = availableSpace(data_dir) log.info("Available space before deleting: {:.2f} GB".format(prev_available_space/1024/1024/1024)) nothing_deleted_count = 0 free_space_status = False while True: # Delete one captured directory captured_dirs_remaining = deleteNightFolders(captured_dir, config) log.info("Deleted dir captured directory: {:s}".format(captured_dir)) log.info("Free space: {:.2f} GB".format(availableSpace(data_dir)/1024/1024/1024)) # Break the there's enough space if availableSpace(data_dir) > next_night_bytes: free_space_status = True break # Delete one archived directory archived_dirs_remaining = deleteNightFolders(archived_dir, config) log.info("Deleted dir in archived directory: {:s}".format(archived_dir)) log.info("Free space: {:.2f} GB".format(availableSpace(data_dir)/1024/1024/1024)) # Break if there's enough space if availableSpace(data_dir) > next_night_bytes: free_space_status = True break # Wait 10 seconds between deletes. This helps to balance out the space distribution if multiple # instances of RMS are running on the same system log.info("Still not enough space, waiting 10 s...") time.sleep(10) # If no folders left to delete, try to delete archived files if (len(captured_dirs_remaining) == 0) and (len(archived_dirs_remaining) == 0): log.info("Deleted all Capture and Archived directories, deleting archived bz2 files...") archived_files_remaining = deleteFiles(archived_dir, config) # If there's nothing left to delete, return False if len(archived_files_remaining) == 0: free_space_status = False break # Break the there's enough space if availableSpace(data_dir) > next_night_bytes: free_space_status = True break # If nothing was deleted in this loop, count how may time this happened if availableSpace(data_dir) == prev_available_space: log.info("Nothing got deleted...") nothing_deleted_count += 1 else: nothing_deleted_count = 0 # If nothing was deleted for 100 loops, indicate that no more space can be freed if nothing_deleted_count >= 100: free_space_status = False break prev_available_space = availableSpace(data_dir) # If there is still not enough space, wait 10 seconds to see if perhaps other users are clearing their # space if this is a multiuser setup if free_space_status == False: time.sleep(10) # If there's still not enough space, return False if availableSpace(data_dir) < next_night_bytes: return False return True
def deleteOldObservations(data_dir, captured_dir, archived_dir, config, duration=None): """ Deletes old observation directories to free up space for new ones. Arguments: data_dir: [str] Path to the RMS data directory which contains the Captured and Archived diretories captured_dir: [str] Captured directory name. archived_dir: [str] Archived directory name. config: [Configuration object] Keyword arguments: duration: [float] Duration of next video capturing in seconds. If None (by default), duration will be calculated for the next night. Return: [bool]: True if there's enough space for the next night's data, False if not. """ captured_dir = os.path.join(data_dir, captured_dir) archived_dir = os.path.join(data_dir, archived_dir) ### Calculate the approximate needed disk space for the next night # If the duration of capture is not given if duration is None: # Time of next local noon #ct = datetime.datetime.utcnow() #noon_time = datetime.datetime(ct.year, ct.month, ct.date, 12) # Initialize the observer and find the time of next noon o = ephem.Observer() o.lat = config.latitude o.long = config.longitude o.elevation = config.elevation sun = ephem.Sun() sunrise = o.previous_rising(sun, start=ephem.now()) noon_time = o.next_transit(sun, start=sunrise).datetime() # if ct.hour > 12: # noon_time += datetime.timedelta(days=1) # Get the duration of the next night _, duration = captureDuration(config.latitude, config.longitude, config.elevation, current_time=noon_time) # Calculate the approx. size for the night night next_night_bytes = (duration * config.fps) / 256 * config.width * config.height * 4 # Always leave at least 2 GB free for archive next_night_bytes += 2 * (1024**3) ###### # If there's enough free space, don't do anything if availableSpace(data_dir) > next_night_bytes: return True # Intermittently delete captured and archived directories until there's enough free space while True: # Delete one captured directory captured_dirs_remaining = deleteNightFolders(captured_dir, config) # Break the there's enough space if availableSpace(data_dir) > next_night_bytes: break # Delete one archived directory archived_dirs_remaining = deleteNightFolders(archived_dir, config) # Break the there's enough space if availableSpace(data_dir) > next_night_bytes: break # If there's nothing left to delete, return False if (len(captured_dirs_remaining) == 0) and (len(archived_dirs_remaining) == 0): return False return True
def deleteOldObservations(data_dir, captured_dir, archived_dir, config, duration=None): """ Deletes old observation directories to free up space for new ones. Arguments: data_dir: [str] Path to the RMS data directory which contains the Captured and Archived diretories captured_dir: [str] Captured directory name. archived_dir: [str] Archived directory name. config: [Configuration object] Keyword arguments: duration: [float] Duration of next video capturing in seconds. If None (by default), duration will be calculated for the next night. Return: [bool]: True if there's enough space for the next night's data, False if not. """ captured_dir = os.path.join(data_dir, captured_dir) archived_dir = os.path.join(data_dir, archived_dir) ### Calculate the approximate needed disk space for the next night # If the duration of capture is not given if duration is None: # Time of next local noon #ct = datetime.datetime.utcnow() #noon_time = datetime.datetime(ct.year, ct.month, ct.date, 12) # Initialize the observer and find the time of next noon o = ephem.Observer() o.lat = config.latitude o.long = config.longitude o.elevation = config.elevation sun = ephem.Sun() sunrise = o.previous_rising(sun, start=ephem.now()) noon_time = o.next_transit(sun, start=sunrise).datetime() # if ct.hour > 12: # noon_time += datetime.timedelta(days=1) # Get the duration of the next night _, duration = captureDuration(config.latitude, config.longitude, config.elevation, current_time=noon_time) # Calculate the approx. size for the night night next_night_bytes = (duration*config.fps)/256*config.width*config.height*4 # Always leave at least 2 GB free for archive next_night_bytes += 2*(1024**3) ###### # If there's enough free space, don't do anything if availableSpace(data_dir) > next_night_bytes: return True # Intermittently delete captured and archived directories until there's enough free space while True: # Delete one captured directory captured_dirs_remaining = deleteNightFolders(captured_dir, config) # Break the there's enough space if availableSpace(data_dir) > next_night_bytes: break # Delete one archived directory archived_dirs_remaining = deleteNightFolders(archived_dir, config) # Break the there's enough space if availableSpace(data_dir) > next_night_bytes: break # If there's nothing left to delete, return False if (len(captured_dirs_remaining) == 0) and (len(archived_dirs_remaining) == 0): return False return True
help="Station latitude from .config file") config_parser.add_argument('--longitude', type=float, \ help="Station longitude from .config file") config_parser.add_argument('--elevation', type=float, \ help="Station elevation from .config file") args = config_parser.parse_args() lat = args.latitude lon = args.longitude elev = args.elevation print("WriteCapture.py, Latitude: ", lat) print("WriteCapture.py, Longitude: ", lon) print("WriteCapture.py, Elevation: ", elev) # Compute and write out the next start time and capture time datetime. start_time, duration_float = captureDuration(lat, lon, elev) if start_time is True: # We will use the ephemeris code directly # to compute the previous sunset time, to get start_time and duration. # Code copied fromCaptureDuration.py # Initialize the observer o = ephem.Observer() o.lat = str(lat) o.long = str(lon) o.elevation = elev # The Sun should be about 5.5 degrees below the horizon when the capture should begin/end o.horizon = '-5:26' # Calculate the locations of the Sun s = ephem.Sun()
def rmsExternal(captured_night_dir, archived_night_dir, config): initLogging(config, 'iStream_') log = logging.getLogger("logger") log.info('iStream external script started') # create lock file to avoid RMS rebooting the system lockfile = os.path.join(config.data_dir, config.reboot_lock_file) with open(lockfile, 'w') as _: pass # Compute the capture duration from now start_time, duration = captureDuration(config.latitude, config.longitude, config.elevation) timenow = datetime.datetime.utcnow() remaining_seconds = 0 # Compute how long to wait before capture if start_time != True: waitingtime = start_time - timenow remaining_seconds = int(waitingtime.total_seconds()) # Run the Istrastream shell script script_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "iStream.sh") log.info('Calling {}'.format(script_path)) command = [ script_path, config.stationID, captured_night_dir, archived_night_dir, '{:.6f}'.format(config.latitude), '{:.6f}'.format(config.longitude), '{:.1f}'.format(config.elevation), str(config.width), str(config.height), str(remaining_seconds) ] proc = subprocess.Popen(command,stdout=subprocess.PIPE) # Read iStream script output and append to log file while True: line = proc.stdout.readline() if not line: break log.info(line.rstrip().decode("utf-8")) exit_code = proc.wait() log.info('Exit status: {}'.format(exit_code)) log.info('iStream external script finished') # relase lock file so RMS is authorized to reboot, if needed os.remove(lockfile) # Reboot the computer (script needs sudo priviledges, works only on Linux) try: log.info("Rebooting system...") os.system('sudo shutdown -r now') except Exception as e: log.debug('Rebooting failed with message:\n' + repr(e)) log.debug(repr(traceback.format_exception(*sys.exc_info())))