1
0
Fork 0

Implement a configurable minimum horizon in network

This commit adds a "horizon" configuration item to stations. This
allows station owners to set a minimum horizon to avoid a noisy
or obstructed floor level.

The default minimum horizon is set to 10, which is still fairly
low for a satellite pass that could be captured but given the
appropriate setup someone may be successful setting it lower.

The horizon field is honored in both the calculation of upcoming
passes in the station view as well as excluding any "below horizon"
passes in prediction_windows.

In addition, the db migration will set a minimum horizon of "10"
for all existing stations in the network. This is the horizon that
was hard-coded for the upcoming passes view so the only change to
the end user will be the behavior of window prediction matching
the upcoming passes (along with the ability to configure their
minimum horizon, of course).
merge-requests/218/head
Corey Shields 2016-03-18 21:59:59 -04:00
parent 79f7ec1d0c
commit b9f549cf0c
6 changed files with 77 additions and 38 deletions

View File

@ -7,5 +7,6 @@ class StationForm(forms.ModelForm):
class Meta:
model = Station
fields = ['name', 'image', 'alt',
'lat', 'lng', 'qthlocator', 'antenna', 'active']
'lat', 'lng', 'qthlocator',
'horizon', 'antenna', 'active']
image = forms.ImageField(required=False)

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9.4 on 2016-03-19 00:49
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('base', '0003_auto_20160119_1856'),
]
operations = [
migrations.AddField(
model_name='station',
name='horizon',
field=models.PositiveIntegerField(default=10, help_text=b'In degrees above 0'),
),
]

View File

@ -57,6 +57,7 @@ class Station(models.Model):
created = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
last_seen = models.DateTimeField(null=True, blank=True)
horizon = models.PositiveIntegerField(help_text='In degrees above 0', default=10)
class Meta:
ordering = ['-active', '-last_seen']

View File

@ -213,49 +213,54 @@ def prediction_windows(request, sat_id, start_date, end_date):
}
break
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")
# 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")
# Adjust or discard window if overlaps exist
window_start = make_aware(ephem.Date(tr).datetime(), utc)
window_end = make_aware(ephem.Date(ts).datetime(), utc)
window = _resolve_overlaps(station, window_start, window_end)
if window:
if not station_match:
station_windows = {
'id': station.id,
'name': station.name,
'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
})
# In case our window was split in two
try:
window_start = window[2]
window_end = window[3]
# Adjust or discard window if overlaps exist
window_start = make_aware(ephem.Date(tr).datetime(), utc)
window_end = make_aware(ephem.Date(ts).datetime(), utc)
window = _resolve_overlaps(station, window_start, window_end)
if window:
if not station_match:
station_windows = {
'id': station.id,
'name': station.name,
'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
})
except:
pass
# In case our window was split in two
try:
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
})
except:
pass
else:
# window start outside of window bounds
break
else:
# window start outside of window bounds
# did not rise above user configured horizon
break
if station_match:
@ -361,9 +366,9 @@ def station_view(request, id):
azimuth = format(math.degrees(azr), '.0f')
passid += 1
# show only if >= 10 degrees and in next 6 hours
# show only if >= configured horizon and in next 6 hours
if tr < ephem.date(datetime.today() + timedelta(hours=6)):
if float(elevation) >= 10:
if float(elevation) >= station.horizon:
sat_pass = {'passid': passid,
'mytime': str(observer.date),
'debug': observer.next_pass(sat_ephem),

View File

@ -73,6 +73,12 @@
{{ station.alt }} m
</span>
</div>
<div class="gs-front-line">
<span class="label label-default">Min Horizon</span>
<span class="gs-front-data">
{{ station.horizon }}°
</span>
</div>
<div class="gs-front-line">
<span class="label label-default">Creation Date</span>
<span class="gs-front-data"

View File

@ -58,6 +58,12 @@
readonly>
</div>
</div>
<div class="form-group">
<label for="horizon" class="col-sm-2 control-label">Minimum Horizon</label>
<div class="col-sm-10">
<input value="{{ form.horizon.value }}" id="horizon" type="text" class="form-control" name="horizon" placeholder="Minimum horizon for passes, default 10">
</div>
</div>
<div class="form-group">
<label for="antennas" class="col-sm-2 control-label">Antennas</label>
<div class="col-sm-10">