1
0
Fork 0

Merge branch 'group-obs-fixes' into 'dev'

Fixes on Observations Group Scheduling

See merge request librespacefoundation/satnogs/satnogs-network!493
environments/stage/deployments/120
Pierros Papadeas 2018-06-28 10:55:55 +00:00
commit 609b8c30cf
4 changed files with 111 additions and 58 deletions

View File

@ -36,24 +36,29 @@ def calculate_polar_data(observer, satellite, start, end, points):
def resolve_overlaps(station, gs_data, start, end):
overlapped = False
if gs_data:
for datum in gs_data:
if datum.is_past:
continue
if datum.start <= end and start <= datum.end:
overlapped = True
if datum.start <= start and datum.end >= end:
return False
return ()
if start < datum.start and end > datum.end:
start1 = start
end1 = datum.start
start2 = datum.end
end1 = datum.start - timedelta(seconds=10)
start2 = datum.end + timedelta(seconds=10)
end2 = end
return start1, end1, start2, end2
if datum.start <= start:
start = datum.end
start = datum.end + timedelta(seconds=10)
if datum.end >= end:
end = datum.start
return start, end
end = datum.start - timedelta(seconds=10)
if overlapped:
return start, end, overlapped
else:
return start, end
def cache_get_key(*args, **kwargs):

View File

@ -235,6 +235,33 @@ def observation_new(request):
messages.error(request, 'Please schedule an observation that begins in the future')
return redirect(reverse('base:observation_new'))
total = int(request.POST.get('total'))
changed = 0
for item in range(total):
start = make_aware(datetime.strptime(
request.POST.get('{0}-starting_time'.format(item)), '%Y-%m-%d %H:%M:%S.%f'
))
end = make_aware(datetime.strptime(
request.POST.get('{}-ending_time'.format(item)), '%Y-%m-%d %H:%M:%S.%f'
))
station_id = request.POST.get('{}-station'.format(item))
station = Station.objects.get(id=station_id)
gs_data = Observation.objects.filter(ground_station=station)
window = resolve_overlaps(station, gs_data, start, end)
if (len(window) > 2 or len(window) == 0):
changed += 1
if changed > 0:
error_message = (
str(changed) + " observations are already scheduled or overlap with others."
" Please recalculate and try schedule them again."
)
if(changed == 1):
error_message = (
"The observation is already scheduled or overlaps with others."
" Please recalculate and try schedule it again.")
messages.error(request, error_message)
return redirect(reverse('base:observation_new'))
start = make_aware(start_time, utc)
end = make_aware(end_time, utc)
sat = Satellite.objects.get(norad_cat_id=sat_id)
@ -247,8 +274,6 @@ def observation_new(request):
observer = ephem.Observer()
observer.date = str(start)
total = int(request.POST.get('total'))
scheduled = []
for item in range(total):
@ -385,26 +410,26 @@ def prediction_windows(request, sat_id, transmitter, start_date, end_date,
observer.elevation = station.alt
observer.date = str(start_date)
station_match = False
keep_digging = True
while keep_digging:
while True:
try:
tr, azr, tt, altt, ts, azs = observer.next_pass(satellite)
except ValueError:
data = {
'error': 'That satellite seems to stay always below your horizon.'
}
if len(stations) == 1:
data = [{
'error': 'That satellite seems to stay always below your horizon.'
}]
break
# no match if the sat will not rise above the configured min horizon
elevation = format(math.degrees(altt), '.0f')
if float(elevation) >= station.horizon:
if ephem.Date(tr).datetime() < end_date:
if ephem.Date(ts).datetime() > end_date:
ts = end_date
keep_digging = False
else:
time_start_new = ephem.Date(ts).datetime() + timedelta(minutes=1)
observer.date = time_start_new.strftime("%Y-%m-%d %H:%M:%S.%f")
if ephem.Date(tr).datetime() < end_date:
if ephem.Date(ts).datetime() > end_date:
break
else:
time_start_new = ephem.Date(ts).datetime() + timedelta(minutes=1)
observer.date = time_start_new.strftime("%Y-%m-%d %H:%M:%S.%f")
if float(elevation) >= station.horizon:
# Adjust or discard window if overlaps exist
window_start = make_aware(ephem.Date(tr).datetime(), utc)
@ -413,40 +438,43 @@ def prediction_windows(request, sat_id, transmitter, start_date, end_date,
# Check if overlaps with existing scheduled observations
gs_data = Observation.objects.filter(ground_station=station)
window = resolve_overlaps(station, gs_data, window_start, window_end)
window_length = len(window)
if window:
if window_length > 0:
if not station_match:
station_windows = {
'id': station.id,
'name': station.name,
'status': station.status,
'window': []
}
station_match = True
window_start = window[0]
window_end = window[1]
station_windows['window'].append(
{
'start': window_start.strftime("%Y-%m-%d %H:%M:%S.%f"),
'end': window_end.strftime("%Y-%m-%d %H:%M:%S.%f"),
'az_start': azr
'az_start': azr,
'overlapped': window_length != 2
})
# In case our window was split in two
try:
if window_length == 4:
# In this case our window was split in two
window_start = window[2]
window_end = window[3]
station_windows['window'].append(
{
'start': window_start.strftime("%Y-%m-%d %H:%M:%S.%f"),
'end': window_end.strftime("%Y-%m-%d %H:%M:%S.%f"),
'az_start': azr
'az_start': azr,
'overlapped': True
})
except IndexError:
pass
else:
# window start outside of window bounds
break
# did not rise above user configured horizon
continue
else:
# did not rise above user configured horizon
# window start outside of window bounds
break
if station_match:

View File

@ -312,9 +312,9 @@ OPBEAT = {
# Observations settings
# Datetimes in minutes for scheduling OPTIONS
OBSERVATION_DATE_MIN_START = config('OBSERVATION_DATE_MIN_START', default=15, cast=int)
OBSERVATION_DATE_MIN_END = config('OBSERVATION_DATE_MIN_START', default=75, cast=int)
OBSERVATION_DATE_MIN_END = config('OBSERVATION_DATE_MIN_START', default=25, cast=int)
# Deletion range in minutes
OBSERVATION_DATE_MAX_RANGE = config('OBSERVATION_DATE_MAX_RANGE', default=480, cast=int)
OBSERVATION_DATE_MAX_RANGE = config('OBSERVATION_DATE_MAX_RANGE', default=2880, cast=int)
# Clean up threshold in days
OBSERVATION_OLD_RANGE = config('OBSERVATION_OLD_RANGE', default=30, cast=int)

View File

@ -22,18 +22,32 @@ $(document).ready( function(){
}
if (!obs_filter_dates) {
var minstart = $('#datetimepicker-start').data('date-minstart');
var minend = $('#datetimepicker-end').data('date-minend');
var maxrange = $('#datetimepicker-end').data('date-maxrange');
$('#datetimepicker-start').datetimepicker();
$('#datetimepicker-start').data('DateTimePicker').minDate(moment.utc().add(minstart, 'm'));
$('#datetimepicker-end').datetimepicker();
$('#datetimepicker-end').data('DateTimePicker').minDate(moment.utc().add(minend, 'm'));
var minStart = $('#datetimepicker-start').data('date-minstart');
var minEnd = $('#datetimepicker-end').data('date-minend');
var maxRange = $('#datetimepicker-end').data('date-maxrange');
var minRange = minEnd - minStart;
var minStartDate = moment().utc().add(minStart, 'm').format('YYYY-MM-DD HH:mm');
var maxStartDate = moment().utc().add(minStart + maxRange - minRange, 'm').format('YYYY-MM-DD HH:mm');
var minEndDate = moment().utc().add(minEnd, 'm').format('YYYY-MM-DD HH:mm');
var maxEndDate = moment().utc().add(minStart + maxRange, 'm').format('YYYY-MM-DD HH:mm');
$('#datetimepicker-start').datetimepicker({
useCurrent: false //https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1075
});
$('#datetimepicker-start').data('DateTimePicker').date(minStartDate);
$('#datetimepicker-start').data('DateTimePicker').minDate(minStartDate);
$('#datetimepicker-start').data('DateTimePicker').maxDate(maxStartDate);
$('#datetimepicker-end').datetimepicker({
useCurrent: false //https://github.com/Eonasdan/bootstrap-datetimepicker/issues/1075
});
$('#datetimepicker-end').data('DateTimePicker').date(minEndDate);
$('#datetimepicker-end').data('DateTimePicker').minDate(minEndDate);
$('#datetimepicker-end').data('DateTimePicker').maxDate(maxEndDate);
$('#datetimepicker-start').on('dp.change',function (e) {
// Setting default, minimum and maximum for end
$('#datetimepicker-end').data('DateTimePicker').defaultDate(moment.utc(e.date).add(60, 'm'));
$('#datetimepicker-end').data('DateTimePicker').minDate(e.date);
$('#datetimepicker-end').data('DateTimePicker').maxDate(moment.utc(e.date).add(maxrange, 'm'));
var newMinEndDate = e.date.clone().add(minRange, 'm');
if ($('#datetimepicker-end').data('DateTimePicker').date() < newMinEndDate) {
$('#datetimepicker-end').data('DateTimePicker').date(newMinEndDate);
}
$('#datetimepicker-end').data('DateTimePicker').minDate(newMinEndDate);
});
}
@ -64,8 +78,8 @@ $(document).ready( function(){
beforeSend: function() { $('#loading').show(); }
}).done(function(data) {
$('#loading').hide();
if (data.error) {
var error_msg = data.error;
if (data.length == 1 && data[0].error) {
var error_msg = data[0].error;
$('#windows-data').html('<span class="text-danger">' + error_msg + '</span>');
} else {
var dc = 0; // Data counter
@ -73,18 +87,24 @@ $(document).ready( function(){
var label = '';
$('#windows-data').empty();
$.each(data, function(i, k){
label = k.id + ' - ' + k.name;
var times = [];
$.each(k.window, function(m, n){
var starting_time = moment.utc(n.start).valueOf();
var ending_time = moment.utc(n.end).valueOf();
$('#windows-data').append('<input type="hidden" name="' + dc + '-starting_time" value="' + n.start + '">');
$('#windows-data').append('<input type="hidden" name="' + dc + '-ending_time" value="' + n.end + '">');
$('#windows-data').append('<input type="hidden" name="' + dc + '-station" value="' + k.id + '">');
times.push({starting_time: starting_time, ending_time: ending_time});
dc = dc + 1;
});
suggested_data.push({label: label, times: times});
if(k.status !== 1 || obs_filter_station){
label = k.id + ' - ' + k.name;
var times = [];
$.each(k.window, function(m, n){
if(!n.overlapped || obs_filter_station){
var starting_time = moment.utc(n.start).valueOf();
var ending_time = moment.utc(n.end).valueOf();
$('#windows-data').append('<input type="hidden" name="' + dc + '-starting_time" value="' + n.start + '">');
$('#windows-data').append('<input type="hidden" name="' + dc + '-ending_time" value="' + n.end + '">');
$('#windows-data').append('<input type="hidden" name="' + dc + '-station" value="' + k.id + '">');
times.push({starting_time: starting_time, ending_time: ending_time});
dc = dc + 1;
}
});
if(times.length > 0){
suggested_data.push({label: label, times: times});
}
}
});
$('#windows-data').append('<input type="hidden" name="total" value="' + dc + '">');