improved configuration
This commit is contained in:
parent
7f96655779
commit
e01254df21
|
|
@ -12,11 +12,15 @@ password="foobar"
|
|||
port="5432"
|
||||
|
||||
;; Settings for the remover script
|
||||
days_to_save_position_data="31"
|
||||
days_to_save_station_data="90"
|
||||
days_to_save_position_data="10"
|
||||
days_to_save_station_data="30"
|
||||
days_to_save_weather_data="10"
|
||||
days_to_save_telemetry_data="10"
|
||||
|
||||
;; If this setting is enabled, OGN stations that we are not allowed to reveal the identity of will be given a random name similar to "UNKNOWN123"
|
||||
;; If disabled we will drop all packets regarding stations that we should not reveal the identity of.
|
||||
save_ogn_stations_with_missing_identity="0"
|
||||
|
||||
|
||||
[websocket_server]
|
||||
|
||||
|
|
@ -29,10 +33,10 @@ port="9000"
|
|||
;; Websocket server log output
|
||||
error_log="~/trackdirect/server/log/wsserver_aprs.log"
|
||||
|
||||
;; Frequency limit
|
||||
;; Packets received more frequently than the configured frequency limit will be dropped
|
||||
;; Frequency limit is specified in seconds, and 0 means that the limit is disabled.
|
||||
;; This setting is very useful when frequency is very high (when receiving data from the OGN network this needs to be at least 15s)
|
||||
;; Packets received more frequently than the configured frequency limit will be dropped (limit is specified in seconds)
|
||||
;; This frequency limit is only refering to pakets that is received in real time from the filtered feed used by the websocket server
|
||||
;; This frequency limit may be a bit more forgiving than the frequence limit on the collector.
|
||||
;; When receiving data from the OGN network this needs to be about 15s or more.
|
||||
frequency_limit="0"
|
||||
|
||||
;; First APRS IS server for the websocket server to connect to.
|
||||
|
|
@ -40,6 +44,7 @@ frequency_limit="0"
|
|||
aprs_host1="127.0.0.1"
|
||||
aprs_port1="14580"
|
||||
|
||||
;; Important that you set the correct source, otherwise it might be handled incorrect
|
||||
;; - Source Id 1: APRS-IS
|
||||
;; - Source Id 2: CWOP
|
||||
;; - Source Id 3: CBAPRS
|
||||
|
|
@ -54,18 +59,18 @@ aprs_source_id1="1"
|
|||
;aprs_source_id2="2"
|
||||
|
||||
;; Allow time travel
|
||||
;; Use this settings to disable data requests with a time interval
|
||||
;; Useful when it is not allowed to show data older than 24h (like when data comes from the OGN network)
|
||||
;; Note that you need to configure the remover script to delete data after 24h as well (if the source require you to do so)
|
||||
;; Use this settings to disable/enable data requests with a time interval (this must be disabled for the OGN network)
|
||||
allow_time_travel="1"
|
||||
|
||||
;; Max default time in seconds (how old packets that will be included in the response)
|
||||
;; Max default time in minutes (how old packets that will be included in the response)
|
||||
;; This setting should be no more than 1440 for for the OGN network.
|
||||
max_default_time="1440"
|
||||
|
||||
;; Max time in seconds when filtering (how old packets that will be included in the response)
|
||||
max_filter_time="14400"
|
||||
;; Max time in minutes when filtering (how old packets that will be included in the response)
|
||||
;; This setting should be no more than 1440 for for the OGN network.
|
||||
max_filter_time="1440"
|
||||
|
||||
;; Time in seconds until idle client is disconnected
|
||||
;; Time in minutes until idle client is disconnected
|
||||
max_client_idle_time="60"
|
||||
|
||||
;; Max age in seconds for real time packets waiting to be sent to client (dropping packets if limit is excceded)
|
||||
|
|
@ -78,6 +83,7 @@ host="127.0.0.1"
|
|||
port_full="10152"
|
||||
port_filtered="14580"
|
||||
|
||||
;; Important that you set the correct source, otherwise it might be handled incorrect
|
||||
;; - Source Id 1: APRS-IS
|
||||
;; - Source Id 2: CWOP
|
||||
;; - Source Id 3: CBAPRS
|
||||
|
|
@ -92,10 +98,8 @@ passcode="-1"
|
|||
;; Database inserts is done in batches
|
||||
numbers_in_batch="50"
|
||||
|
||||
;; Frequency limit
|
||||
;; Packets received more frequently than the configured frequency limit will not be shown on map.
|
||||
;; Frequency limit is specified per station in seconds, and 0 means that the limit is disabled.
|
||||
;; This setting is very useful when frequency is very high (when receiving data from the OGN network this needs to be at least 20s).
|
||||
;; Packets received more frequently than the configured frequency limit will not be shown on map (limit is specified in seconds)
|
||||
;; When receiving data from the OGN network this needs to be 20s or more.
|
||||
;; If setting save_fast_packets to "0", packets that is received to frequently will not be save (useful for OGN, but not for APRS-IS).
|
||||
frequency_limit="5"
|
||||
save_fast_packets="1"
|
||||
|
|
|
|||
|
|
@ -1744,4 +1744,35 @@ function getSymbolDescription($symbolTable, $symbol, $includeUndefinedOverlay)
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returnes true if the time travel feature works
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
function isTimeTravelAllowed() {
|
||||
$isTimeTravelAllowed = false;
|
||||
$config = parse_ini_file(ROOT . '/../config/trackdirect.ini', true);
|
||||
|
||||
if (isset($config['websocket_server'])) {
|
||||
if (isset($config['websocket_server']['allow_time_travel'])) {
|
||||
if ($config['websocket_server']['allow_time_travel'] == '1') {
|
||||
$isTimeTravelAllowed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($config['websocket_server']['aprs_source_id1']) && $config['websocket_server']['aprs_source_id1'] == 5) {
|
||||
// Data source is OGN, disable time travel (server will block it anyway)
|
||||
$isTimeTravelAllowed = false;
|
||||
}
|
||||
|
||||
if (isset($config['websocket_server']['aprs_source_id2']) && $config['websocket_server']['aprs_source_id2'] == 5) {
|
||||
// Data source is OGN, disable time travel (server will block it anyway)
|
||||
$isTimeTravelAllowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $isTimeTravelAllowed;
|
||||
}
|
||||
|
|
@ -299,62 +299,70 @@
|
|||
<span class="modal-title">Travel in time</h2>
|
||||
</div>
|
||||
<div class="modal-content-body" style="margin: 0px 20px 20px 20px;">
|
||||
<p>Select date and time to show map data for (enter time for your locale time zone). The regular time length select box can still be used to select how old data that should be shown (relative to selected date and time).</p>
|
||||
<p>*Note that the heatmap will still based on data from the latest hour (not the selected date and time).</p>
|
||||
<p>Date and time:</p>
|
||||
<?php if (!isTimeTravelAllowed()) : ?>
|
||||
<div style="text-align: center;">
|
||||
<p style="max-width: 800px; display: inline-block; color: red;">
|
||||
The time travel feature that allows you to see the map as it looked like an earlier date is disabled on this website. The reason is probably that it is a requirement from the data source used.
|
||||
</p>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<p>Select date and time to show map data for (enter time for your locale time zone). The regular time length select box can still be used to select how old data that should be shown (relative to selected date and time).</p>
|
||||
<p>*Note that the heatmap will still based on data from the latest hour (not the selected date and time).</p>
|
||||
<p>Date and time:</p>
|
||||
|
||||
<form id="timetravel-form">
|
||||
<select id="timetravel-date" class="timetravel-select form-control">
|
||||
<option value="0" selected>Select date</option>
|
||||
<?php for($i=0; $i <= 10; $i++) : ?>
|
||||
<?php $date = date('Y-m-d', strtotime("-$i days")); ?>
|
||||
<option value="<?php echo $date; ?>"><?php echo $date; ?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
<form id="timetravel-form">
|
||||
<select id="timetravel-date" class="timetravel-select form-control"
|
||||
<option value="0" selected>Select date</option>
|
||||
<?php for($i=0; $i <= 10; $i++) : ?>
|
||||
<?php $date = date('Y-m-d', strtotime("-$i days")); ?>
|
||||
<option value="<?php echo $date; ?>"><?php echo $date; ?></option>
|
||||
<?php endfor; ?>
|
||||
</select>
|
||||
|
||||
<select id="timetravel-time" class="timetravel-select form-control">
|
||||
<option value="0" selected>Select time</option>
|
||||
<option value="00:00">00:00</option>
|
||||
<option value="01:00">01:00</option>
|
||||
<option value="02:00">02:00</option>
|
||||
<option value="03:00">03:00</option>
|
||||
<option value="04:00">04:00</option>
|
||||
<option value="05:00">05:00</option>
|
||||
<option value="06:00">06:00</option>
|
||||
<option value="07:00">07:00</option>
|
||||
<option value="08:00">08:00</option>
|
||||
<option value="09:00">09:00</option>
|
||||
<option value="10:00">10:00</option>
|
||||
<option value="11:00">11:00</option>
|
||||
<option value="12:00">12:00</option>
|
||||
<option value="13:00">13:00</option>
|
||||
<option value="14:00">14:00</option>
|
||||
<option value="15:00">15:00</option>
|
||||
<option value="16:00">16:00</option>
|
||||
<option value="17:00">17:00</option>
|
||||
<option value="18:00">18:00</option>
|
||||
<option value="19:00">19:00</option>
|
||||
<option value="20:00">20:00</option>
|
||||
<option value="21:00">21:00</option>
|
||||
<option value="22:00">22:00</option>
|
||||
<option value="23:00">23:00</option>
|
||||
</select>
|
||||
<input type="submit"
|
||||
value="Ok"
|
||||
onclick="
|
||||
if ($('#timetravel-date').val() != '0' && $('#timetravel-time').val() != '0') {
|
||||
trackdirect.setTimeLength(60, false);
|
||||
var ts = moment($('#timetravel-date').val() + ' ' + $('#timetravel-time').val(), 'YYYY-MM-DD HH:mm').unix();
|
||||
trackdirect.setTimeTravelTimestamp(ts);
|
||||
$('#right-container-timetravel-content').html('Time travel to ' + $('#timetravel-date').val() + ' ' + $('#timetravel-time').val());
|
||||
$('#right-container-timetravel').show();
|
||||
} else {
|
||||
trackdirect.setTimeTravelTimestamp(0, true);
|
||||
$('#right-container-timetravel').hide();
|
||||
}
|
||||
$('#modal-timetravel').hide();
|
||||
return false;"/>
|
||||
</form>
|
||||
<select id="timetravel-time" class="timetravel-select form-control">
|
||||
<option value="0" selected>Select time</option>
|
||||
<option value="00:00">00:00</option>
|
||||
<option value="01:00">01:00</option>
|
||||
<option value="02:00">02:00</option>
|
||||
<option value="03:00">03:00</option>
|
||||
<option value="04:00">04:00</option>
|
||||
<option value="05:00">05:00</option>
|
||||
<option value="06:00">06:00</option>
|
||||
<option value="07:00">07:00</option>
|
||||
<option value="08:00">08:00</option>
|
||||
<option value="09:00">09:00</option>
|
||||
<option value="10:00">10:00</option>
|
||||
<option value="11:00">11:00</option>
|
||||
<option value="12:00">12:00</option>
|
||||
<option value="13:00">13:00</option>
|
||||
<option value="14:00">14:00</option>
|
||||
<option value="15:00">15:00</option>
|
||||
<option value="16:00">16:00</option>
|
||||
<option value="17:00">17:00</option>
|
||||
<option value="18:00">18:00</option>
|
||||
<option value="19:00">19:00</option>
|
||||
<option value="20:00">20:00</option>
|
||||
<option value="21:00">21:00</option>
|
||||
<option value="22:00">22:00</option>
|
||||
<option value="23:00">23:00</option>
|
||||
</select>
|
||||
<input type="submit"
|
||||
value="Ok"
|
||||
onclick="
|
||||
if ($('#timetravel-date').val() != '0' && $('#timetravel-time').val() != '0') {
|
||||
trackdirect.setTimeLength(60, false);
|
||||
var ts = moment($('#timetravel-date').val() + ' ' + $('#timetravel-time').val(), 'YYYY-MM-DD HH:mm').unix();
|
||||
trackdirect.setTimeTravelTimestamp(ts);
|
||||
$('#right-container-timetravel-content').html('Time travel to ' + $('#timetravel-date').val() + ' ' + $('#timetravel-time').val());
|
||||
$('#right-container-timetravel').show();
|
||||
} else {
|
||||
trackdirect.setTimeTravelTimestamp(0, true);
|
||||
$('#right-container-timetravel').hide();
|
||||
}
|
||||
$('#modal-timetravel').hide();
|
||||
return false;"/>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ if __name__ == '__main__':
|
|||
collectorNumber = int(sys.argv[2])
|
||||
collectorOptions = config.collector[collectorNumber]
|
||||
|
||||
saveOgnStationsWithMissingIdentity = False
|
||||
if (config.saveOgnStationsWithMissingIdentity) :
|
||||
saveOgnStationsWithMissingIdentity = True
|
||||
|
||||
fh = logging.handlers.RotatingFileHandler(filename=os.path.expanduser(
|
||||
collectorOptions['error_log']), mode='a', maxBytes=1000000, backupCount=10)
|
||||
fh.setLevel(logging.WARNING)
|
||||
|
|
@ -47,7 +51,8 @@ if __name__ == '__main__':
|
|||
|
||||
try:
|
||||
trackDirectDataCollector = trackdirect.TrackDirectDataCollector(
|
||||
collectorOptions)
|
||||
collectorOptions,
|
||||
saveOgnStationsWithMissingIdentity)
|
||||
trackDirectDataCollector.run()
|
||||
except Exception as e:
|
||||
trackDirectLogger.error(e, exc_info=1)
|
||||
|
|
|
|||
|
|
@ -48,6 +48,15 @@ class TrackDirectConfig(Singleton):
|
|||
self.daysToSaveTelemetryData = int(configParser.get(
|
||||
'database', 'days_to_save_telemetry_data').strip('"'))
|
||||
|
||||
self.saveOgnStationsWithMissingIdentity = False
|
||||
try:
|
||||
saveOgnStationsWithMissingIdentity = configParser.get(
|
||||
'database', 'save_ogn_stations_with_missing_identity').strip('"')
|
||||
if (saveOgnStationsWithMissingIdentity == "1"):
|
||||
self.saveOgnStationsWithMissingIdentity = True
|
||||
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
|
||||
pass
|
||||
|
||||
# Websocket server
|
||||
self.websocketHostname = configParser.get(
|
||||
'websocket_server', 'host').strip('"')
|
||||
|
|
@ -69,11 +78,11 @@ class TrackDirectConfig(Singleton):
|
|||
|
||||
allowTimeTravel = configParser.get(
|
||||
'websocket_server', 'allow_time_travel').strip('"')
|
||||
self.allowTimeTravel = True
|
||||
if (allowTimeTravel == "0"):
|
||||
self.allowTimeTravel = False
|
||||
self.allowTimeTravel = False
|
||||
if (allowTimeTravel == "1"):
|
||||
self.allowTimeTravel = True
|
||||
|
||||
# Websocket server APRS-IS connection
|
||||
# Websocket server APRS connection (we support 2 different sources, more can be added...)
|
||||
try:
|
||||
self.websocketAprsHost1 = configParser.get(
|
||||
'websocket_server', 'aprs_host1').strip('"')
|
||||
|
|
@ -98,6 +107,14 @@ class TrackDirectConfig(Singleton):
|
|||
self.websocketAprsHost2 = None
|
||||
self.websocketAprsPort2 = None
|
||||
|
||||
if (self.websocketAprsSourceId1 == 5 or self.websocketAprsSourceId2 == 5) :
|
||||
# At least one source is of type OGN, disable display of older data
|
||||
self.allowTimeTravel = False
|
||||
if (self.maxDefaultTime > 1440) :
|
||||
self.maxDefaultTime = 1440
|
||||
if (self.maxFilterTime > 1440) :
|
||||
self.maxDefaultTime = 1440
|
||||
|
||||
# Collectors
|
||||
for collectorNumber in range(0, 5):
|
||||
self.collector[collectorNumber] = {}
|
||||
|
|
@ -129,6 +146,13 @@ class TrackDirectConfig(Singleton):
|
|||
self.collector[collectorNumber]['error_log'] = configParser.get(
|
||||
'collector' + str(collectorNumber), 'error_log').strip('"')
|
||||
|
||||
if (self.websocketAprsSourceId1 == 5 or self.websocketAprsSourceId2 == 5) :
|
||||
# source is of type OGN, make sure we do not save to many packets (will cause to high load on db)
|
||||
if (self.collector[collectorNumber]['frequency_limit'] < 10) :
|
||||
self.collector[collectorNumber]['frequency_limit'] = 10
|
||||
self.collector[collectorNumber]['save_fast_packets'] = False
|
||||
|
||||
|
||||
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
|
||||
self.collector[collectorNumber]['source_id'] = None
|
||||
self.collector[collectorNumber]['host'] = None
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ from trackdirect.database.DatabaseConnection import DatabaseConnection
|
|||
from trackdirect.repositories.StationRepository import StationRepository
|
||||
from trackdirect.objects.Packet import Packet
|
||||
|
||||
|
||||
class TrackDirectDataCollector():
|
||||
"""An TrackDirectDataCollector instance connects to the data source and saves all received packets to the database
|
||||
|
||||
|
|
@ -28,12 +27,14 @@ class TrackDirectDataCollector():
|
|||
This is useful if you want one connection to the regular APRS-IS network and one connection to the CWOP network.
|
||||
"""
|
||||
|
||||
def __init__(self, collectorOptions):
|
||||
def __init__(self, collectorOptions, saveOgnStationsWithMissingIdentity):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
collectorOptions (dict): Contains data like host, port, callsign, passcode, source id
|
||||
collectorOptions (dict): Contains data like host, port, callsign, passcode, source id
|
||||
saveOgnStationsWithMissingIdentity (boolean): True if we should not ignore stationss with a missing identity
|
||||
"""
|
||||
self.saveOgnStationsWithMissingIdentity = saveOgnStationsWithMissingIdentity
|
||||
self.sourceHostname = collectorOptions['host']
|
||||
self.sourcePort = collectorOptions['port_full']
|
||||
self.numbersInBatch = collectorOptions['numbers_in_batch']
|
||||
|
|
@ -142,7 +143,7 @@ class TrackDirectDataCollector():
|
|||
'Collector has a delay on %s seconds', self.delay)
|
||||
|
||||
packetDict = aprslib.parse(line)
|
||||
parser = AprsPacketParser(self.db)
|
||||
parser = AprsPacketParser(self.db, self.saveOgnStationsWithMissingIdentity)
|
||||
parser.setSourceId(self.sourceId)
|
||||
packet = parser.getPacket(packetDict, timestamp)
|
||||
|
||||
|
|
@ -177,7 +178,7 @@ class TrackDirectDataCollector():
|
|||
try:
|
||||
line = line.decode('utf-8', 'ignore')
|
||||
packetDict = self.basicParse(line)
|
||||
parser = AprsPacketParser(self.db)
|
||||
parser = AprsPacketParser(self.db, self.saveOgnStationsWithMissingIdentity)
|
||||
parser.setSourceId(self.sourceId)
|
||||
packet = parser.getPacket(packetDict, timestamp, True)
|
||||
packet.markerId = 1
|
||||
|
|
|
|||
|
|
@ -51,13 +51,15 @@ class AprsPacketParser():
|
|||
"""AprsPacketParser tackes a aprslib output and converts it to a Trackdirect Packet
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
def __init__(self, db, saveOgnStationsWithMissingIdentity):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
db (psycopg2.Connection): Database connection
|
||||
saveOgnStationsWithMissingIdentity (boolean): True if we should not ignore stationss with a missing identity
|
||||
"""
|
||||
self.db = db
|
||||
self.saveOgnStationsWithMissingIdentity = saveOgnStationsWithMissingIdentity
|
||||
self.logger = logging.getLogger('trackdirect')
|
||||
|
||||
self.databaseWriteAccess = True
|
||||
|
|
@ -315,6 +317,9 @@ class AprsPacketParser():
|
|||
return
|
||||
|
||||
elif (not ognDataPolicy.isAllowedToIdentify):
|
||||
if (not self.saveOgnStationsWithMissingIdentity) :
|
||||
self.packet.mapId = 15
|
||||
return
|
||||
self.isHiddenStation = True
|
||||
self.data["from"] = self._getHiddenStationName()
|
||||
self.data["object_name"] = None
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ class AprsISPayloadCreator():
|
|||
self.config = TrackDirectConfig()
|
||||
self.stationHashTimestamps = {}
|
||||
|
||||
self.saveOgnStationsWithMissingIdentity = False
|
||||
if (self.config.saveOgnStationsWithMissingIdentity) :
|
||||
self.saveOgnStationsWithMissingIdentity = True
|
||||
|
||||
|
||||
def getPayloads(self, line, sourceId):
|
||||
"""Takes a raw packet and returnes a dict with the parsed result
|
||||
|
|
@ -85,7 +89,7 @@ class AprsISPayloadCreator():
|
|||
Packet
|
||||
"""
|
||||
basicPacketDict = aprslib.parse(line)
|
||||
parser = AprsPacketParser(self.db)
|
||||
parser = AprsPacketParser(self.db, self.saveOgnStationsWithMissingIdentity)
|
||||
parser.setDatabaseWriteAccess(False)
|
||||
parser.setSourceId(sourceId)
|
||||
try :
|
||||
|
|
|
|||
Loading…
Reference in New Issue