kopia lustrzana https://github.com/glidernet/ogn-python
No more stats table -> functionality of TimescaleDB
Changed PK in tables device/receiver from id to name Altered FK in table takeoff_landings/logbook from device_id to address Updated Flarm release datespull/78/head
rodzic
695478654b
commit
a18e6aeab3
|
@ -22,7 +22,6 @@ CELERYBEAT_SCHEDULE = {
|
|||
"update-takeoff-and-landing": {"task": "update_takeoff_landings", "schedule": timedelta(hours=1), "kwargs": {"last_minutes": 90}},
|
||||
"update-logbook": {"task": "update_logbook_entries", "schedule": timedelta(hours=2), "kwargs": {"day_offset": 0}},
|
||||
"update-max-altitudes": {"task": "update_logbook_max_altitude", "schedule": timedelta(hours=1), "kwargs": {"day_offset": 0}},
|
||||
"update-stats-daily": {"task": "update_stats", "schedule": crontab(hour=0, minute=5), "kwargs": {"day_offset": -1}},
|
||||
"update-logbook-daily": {"task": "update_logbook_entries", "schedule": crontab(hour=1, minute=0), "kwargs": {"day_offset": -1}},
|
||||
"purge_old_data": {"task": "purge_old_data", "schedule": timedelta(hours=1), "kwargs": {"max_hours": 48}},
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ from flask import request, render_template, send_file
|
|||
|
||||
from app import db
|
||||
from app import cache
|
||||
from app.model import Airport, Country, Device, Logbook, Receiver, ReceiverStats
|
||||
from app.model import Airport, Country, Device, Logbook, Receiver
|
||||
|
||||
from app.main import bp
|
||||
|
||||
|
@ -184,14 +184,3 @@ def download_flight():
|
|||
buffer.seek(0)
|
||||
|
||||
return send_file(buffer, as_attachment=True, attachment_filename="wtf.igc", mimetype="text/plain")
|
||||
|
||||
|
||||
@bp.route("/statistics.html")
|
||||
def statistics():
|
||||
|
||||
today = datetime.date.today()
|
||||
today = datetime.date(2018, 7, 31)
|
||||
|
||||
receiverstats = db.session.query(ReceiverStats).filter(ReceiverStats.date == today)
|
||||
|
||||
return render_template("statistics.html", title="Receiver Statistics", receiverstats=receiverstats)
|
||||
|
|
|
@ -2,20 +2,14 @@
|
|||
from .aircraft_type import AircraftType
|
||||
from .beacon import Beacon
|
||||
from .country import Country
|
||||
from .country_stats import CountryStats
|
||||
from .device import Device
|
||||
from .device_info import DeviceInfo
|
||||
from .device_info_origin import DeviceInfoOrigin
|
||||
from .device_stats import DeviceStats
|
||||
from .aircraft_beacon import AircraftBeacon
|
||||
from .receiver_beacon import ReceiverBeacon
|
||||
from .receiver import Receiver
|
||||
from .receiver_stats import ReceiverStats
|
||||
from .takeoff_landing import TakeoffLanding
|
||||
from .airport import Airport
|
||||
from .logbook import Logbook
|
||||
from .receiver_coverage import ReceiverCoverage
|
||||
from .relation_stats import RelationStats
|
||||
from .flights2d import Flight2D
|
||||
|
||||
from .geo import Location
|
||||
|
|
|
@ -30,8 +30,8 @@ class AircraftBeacon(Beacon):
|
|||
distance = db.Column(db.Float(precision=2))
|
||||
radial = db.Column(db.SmallInteger)
|
||||
quality = db.Column(db.Float(precision=2)) # signal quality normalized to 10km
|
||||
location_mgrs = db.Column(db.String(15)) # full mgrs (15 chars)
|
||||
location_mgrs_short = db.Column(db.String(9)) # reduced mgrs (9 chars), e.g. used for melissas range tool
|
||||
location_mgrs = db.Column(db.String(15)) # full mgrs (15 chars)
|
||||
location_mgrs_short = db.Column(db.String(9)) # reduced mgrs (9 chars), e.g. used for melissas range tool
|
||||
agl = db.Column(db.Float(precision=2))
|
||||
|
||||
def __repr__(self):
|
||||
|
@ -56,75 +56,5 @@ class AircraftBeacon(Beacon):
|
|||
self.quality,
|
||||
self.location_mgrs,
|
||||
self.location_mgrs_short,
|
||||
self.agl,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_columns(self):
|
||||
return [
|
||||
"location",
|
||||
"altitude",
|
||||
"name",
|
||||
"dstcall",
|
||||
"relay",
|
||||
"receiver_name",
|
||||
"timestamp",
|
||||
"track",
|
||||
"ground_speed",
|
||||
# 'raw_message',
|
||||
# 'reference_timestamp',
|
||||
"address_type",
|
||||
"aircraft_type",
|
||||
"stealth",
|
||||
"address",
|
||||
"climb_rate",
|
||||
"turn_rate",
|
||||
"signal_quality",
|
||||
"error_count",
|
||||
"frequency_offset",
|
||||
"gps_quality_horizontal",
|
||||
"gps_quality_vertical",
|
||||
"software_version",
|
||||
"hardware_version",
|
||||
"real_address",
|
||||
"signal_power",
|
||||
"distance",
|
||||
"radial",
|
||||
"quality",
|
||||
"location_mgrs",
|
||||
"location_mgrs_short",
|
||||
]
|
||||
|
||||
def get_values(self):
|
||||
return [
|
||||
self.location_wkt,
|
||||
int(self.altitude) if self.altitude else None,
|
||||
self.name,
|
||||
self.dstcall,
|
||||
self.relay,
|
||||
self.receiver_name,
|
||||
self.timestamp,
|
||||
self.track,
|
||||
self.ground_speed,
|
||||
# self.raw_message,
|
||||
# self.reference_timestamp,
|
||||
self.address_type,
|
||||
self.aircraft_type,
|
||||
self.stealth,
|
||||
self.address,
|
||||
self.climb_rate,
|
||||
self.turn_rate,
|
||||
self.signal_quality,
|
||||
self.error_count,
|
||||
self.frequency_offset,
|
||||
self.gps_quality_horizontal,
|
||||
self.gps_quality_vertical,
|
||||
self.software_version,
|
||||
self.hardware_version,
|
||||
self.real_address,
|
||||
self.signal_power,
|
||||
self.distance,
|
||||
self.radial,
|
||||
self.quality,
|
||||
self.location_mgrs,
|
||||
self.location_mgrs_short,
|
||||
]
|
||||
|
|
|
@ -10,14 +10,14 @@ from app import db
|
|||
|
||||
class Beacon(AbstractConcreteBase, db.Model):
|
||||
# APRS data
|
||||
location_wkt = db.Column("location", Geometry("POINT", srid=4326))
|
||||
location = db.Column("location", Geometry("POINT", srid=4326))
|
||||
altitude = db.Column(db.Float(precision=2))
|
||||
|
||||
name = db.Column(db.String, primary_key=True, nullable=True)
|
||||
name = db.Column(db.String, primary_key=True)
|
||||
dstcall = db.Column(db.String)
|
||||
relay = db.Column(db.String)
|
||||
receiver_name = db.Column(db.String(9), primary_key=True, nullable=True)
|
||||
timestamp = db.Column(db.DateTime, primary_key=True, nullable=True)
|
||||
receiver_name = db.Column(db.String(9), primary_key=True)
|
||||
timestamp = db.Column(db.DateTime, primary_key=True)
|
||||
symboltable = None
|
||||
symbolcode = None
|
||||
track = db.Column(db.SmallInteger)
|
||||
|
@ -31,15 +31,3 @@ class Beacon(AbstractConcreteBase, db.Model):
|
|||
# Debug information
|
||||
raw_message = None
|
||||
reference_timestamp = None
|
||||
|
||||
@hybrid_property
|
||||
def location(self):
|
||||
if self.location_wkt is None:
|
||||
return None
|
||||
|
||||
coords = to_shape(self.location_wkt)
|
||||
return Location(lat=coords.y, lon=coords.x)
|
||||
|
||||
@location.expression
|
||||
def location(cls):
|
||||
return cls.location_wkt
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
from app import db
|
||||
|
||||
|
||||
class CountryStats(db.Model):
|
||||
__tablename__ = "country_stats"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
date = db.Column(db.Date)
|
||||
|
||||
# Static data
|
||||
aircraft_beacon_count = db.Column(db.Integer)
|
||||
device_count = db.Column(db.Integer)
|
||||
|
||||
# Relations
|
||||
country_id = db.Column(db.Integer, db.ForeignKey("countries.gid", ondelete="SET NULL"), index=True)
|
||||
country = db.relationship("Country", foreign_keys=[country_id], backref=db.backref("stats", order_by="CountryStats.date.asc()"))
|
|
@ -10,9 +10,8 @@ from app.model.aircraft_type import AircraftType
|
|||
class Device(db.Model):
|
||||
__tablename__ = "devices"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String, primary_key=True)
|
||||
|
||||
name = db.Column(db.String, index=True)
|
||||
# address = db.Column(db.String(6), index=True)
|
||||
address = db.Column(db.String, index=True)
|
||||
firstseen = db.Column(db.DateTime, index=True)
|
||||
|
@ -38,6 +37,9 @@ class Device(db.Model):
|
|||
return [info for info in query.all()]
|
||||
|
||||
EXPIRY_DATES = {
|
||||
7.0: datetime.date(2021, 10, 31),
|
||||
6.83: datetime.date(2021, 10, 31),
|
||||
6.82: datetime.date(2021, 5, 31),
|
||||
6.81: datetime.date(2021, 1, 31),
|
||||
6.80: datetime.date(2021, 1, 31),
|
||||
6.67: datetime.date(2020, 10, 31),
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
from app import db
|
||||
|
||||
from .aircraft_type import AircraftType
|
||||
|
||||
|
||||
class DeviceStats(db.Model):
|
||||
__tablename__ = "device_stats"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
date = db.Column(db.Date)
|
||||
|
||||
# Static data
|
||||
name = db.Column(db.String)
|
||||
firstseen = db.Column(db.DateTime)
|
||||
lastseen = db.Column(db.DateTime)
|
||||
aircraft_type = db.Column(db.Enum(AircraftType), nullable=False, default=AircraftType.UNKNOWN)
|
||||
stealth = db.Column(db.Boolean)
|
||||
software_version = db.Column(db.Float(precision=2))
|
||||
hardware_version = db.Column(db.SmallInteger)
|
||||
real_address = db.Column(db.String(6))
|
||||
|
||||
# Statistic data
|
||||
max_altitude = db.Column(db.Float(precision=2))
|
||||
receiver_count = db.Column(db.SmallInteger)
|
||||
aircraft_beacon_count = db.Column(db.Integer)
|
||||
jumps = db.Column(db.SmallInteger)
|
||||
ambiguous = db.Column(db.Boolean)
|
||||
quality = db.Column(db.Float(precision=2))
|
||||
|
||||
# Relation statistic data
|
||||
quality_offset = db.Column(db.Float(precision=2))
|
||||
|
||||
# Ranking data
|
||||
max_altitude_ranking_worldwide = db.Column(db.Integer)
|
||||
max_altitude_ranking_country = db.Column(db.Integer)
|
||||
receiver_count_ranking_worldwide = db.Column(db.Integer)
|
||||
receiver_count_ranking_country = db.Column(db.Integer)
|
||||
aircraft_beacon_count_ranking_worldwide = db.Column(db.Integer)
|
||||
aircraft_beacon_count_ranking_country = db.Column(db.Integer)
|
||||
quality_ranking_worldwide = db.Column(db.Integer)
|
||||
quality_ranking_country = db.Column(db.Integer)
|
||||
|
||||
# Relations
|
||||
device_id = db.Column(db.Integer, db.ForeignKey("devices.id", ondelete="SET NULL"), index=True)
|
||||
device = db.relationship("Device", foreign_keys=[device_id], backref=db.backref("stats", order_by="DeviceStats.date.asc()"))
|
||||
|
||||
def __repr__(self):
|
||||
return "<DeviceStats: %s,%s,%s,%s>" % (self.date, self.receiver_count, self.aircraft_beacon_count, self.max_altitude)
|
||||
|
||||
|
||||
db.Index("ix_device_stats_date_device_id", DeviceStats.date, DeviceStats.device_id)
|
|
@ -1,24 +0,0 @@
|
|||
from geoalchemy2.types import Geometry
|
||||
|
||||
from app import db
|
||||
|
||||
|
||||
class Flight2D(db.Model):
|
||||
__tablename__ = "flights2d"
|
||||
|
||||
date = db.Column(db.Date, primary_key=True)
|
||||
flight_type = db.Column(db.SmallInteger, primary_key=True)
|
||||
|
||||
path_wkt = db.Column("path", Geometry("MULTILINESTRING", srid=4326))
|
||||
path_simple_wkt = db.Column("path_simple", Geometry("MULTILINESTRING", srid=4326)) # this is the path simplified with ST_Simplify(path, 0.0001)
|
||||
|
||||
# Relations
|
||||
device_id = db.Column(db.Integer, db.ForeignKey("devices.id", ondelete="SET NULL"), primary_key=True)
|
||||
device = db.relationship("Device", foreign_keys=[device_id], backref="flights2d")
|
||||
|
||||
def __repr__(self):
|
||||
return "<Flight %s: %s,%s>" % (self.date, self.path_wkt, self.path_simple_wkt)
|
||||
|
||||
|
||||
db.Index("ix_flights2d_date_device_id", Flight2D.date, Flight2D.device_id)
|
||||
# db.Index('ix_flights2d_date_path', Flight2D.date, Flight2D.path_wkt) --> CREATE INDEX ix_flights2d_date_path ON flights2d USING GIST("date", path)
|
|
@ -9,6 +9,7 @@ class Logbook(db.Model):
|
|||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
reftime = db.Column(db.DateTime, index=True)
|
||||
address = db.Column(db.String, index=True)
|
||||
takeoff_timestamp = db.Column(db.DateTime)
|
||||
takeoff_track = db.Column(db.SmallInteger)
|
||||
landing_timestamp = db.Column(db.DateTime)
|
||||
|
@ -22,9 +23,6 @@ class Logbook(db.Model):
|
|||
landing_airport_id = db.Column(db.Integer, db.ForeignKey("airports.id", ondelete="CASCADE"), index=True)
|
||||
landing_airport = db.relationship("Airport", foreign_keys=[landing_airport_id])
|
||||
|
||||
device_id = db.Column(db.Integer, db.ForeignKey("devices.id", ondelete="CASCADE"), index=True)
|
||||
device = db.relationship("Device", foreign_keys=[device_id], backref=db.backref("logbook", order_by="Logbook.reftime"))
|
||||
|
||||
@hybrid_property
|
||||
def duration(self):
|
||||
return None if (self.landing_timestamp is None or self.takeoff_timestamp is None) else self.landing_timestamp - self.takeoff_timestamp
|
||||
|
|
|
@ -9,14 +9,13 @@ from app import db
|
|||
class Receiver(db.Model):
|
||||
__tablename__ = "receivers"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
name = db.Column(db.String(9), primary_key=True)
|
||||
location_wkt = db.Column("location", Geometry("POINT", srid=4326))
|
||||
altitude = db.Column(db.Float(precision=2))
|
||||
|
||||
name = db.Column(db.String(9), index=True)
|
||||
firstseen = db.Column(db.DateTime, index=True)
|
||||
lastseen = db.Column(db.DateTime, index=True)
|
||||
timestamp = db.Column(db.DateTime, index=True)
|
||||
version = db.Column(db.String)
|
||||
platform = db.Column(db.String)
|
||||
|
||||
|
|
|
@ -18,28 +18,3 @@ class ReceiverBeacon(Beacon):
|
|||
self.receiver_name,
|
||||
self.timestamp,
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def get_columns(self):
|
||||
return [
|
||||
"location",
|
||||
"altitude",
|
||||
"name",
|
||||
"dstcall",
|
||||
"receiver_name",
|
||||
"timestamp",
|
||||
# 'raw_message',
|
||||
# 'reference_timestamp',
|
||||
]
|
||||
|
||||
def get_values(self):
|
||||
return [
|
||||
self.location_wkt,
|
||||
int(self.altitude) if self.altitude else None,
|
||||
self.name,
|
||||
self.dstcall,
|
||||
self.receiver_name,
|
||||
self.timestamp,
|
||||
# self.raw_message,
|
||||
# self.reference_timestamp,
|
||||
]
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
from app import db
|
||||
|
||||
|
||||
class ReceiverCoverage(db.Model):
|
||||
__tablename__ = "receiver_coverages"
|
||||
|
||||
location_mgrs_short = db.Column(db.String(9), primary_key=True)
|
||||
date = db.Column(db.Date, primary_key=True)
|
||||
|
||||
max_signal_quality = db.Column(db.Float)
|
||||
max_altitude = db.Column(db.Float(precision=2))
|
||||
min_altitude = db.Column(db.Float(precision=2))
|
||||
aircraft_beacon_count = db.Column(db.Integer)
|
||||
|
||||
device_count = db.Column(db.SmallInteger)
|
||||
|
||||
# Relations
|
||||
receiver_id = db.Column(db.Integer, db.ForeignKey("receivers.id", ondelete="SET NULL"), primary_key=True)
|
||||
receiver = db.relationship("Receiver", foreign_keys=[receiver_id], backref=db.backref("receiver_coverages", order_by="ReceiverCoverage.date.asc()"))
|
||||
|
||||
|
||||
db.Index("ix_receiver_coverages_date_receiver_id", ReceiverCoverage.date, ReceiverCoverage.receiver_id)
|
||||
db.Index("ix_receiver_coverages_receiver_id_date", ReceiverCoverage.receiver_id, ReceiverCoverage.date)
|
|
@ -1,41 +0,0 @@
|
|||
from geoalchemy2.types import Geometry
|
||||
|
||||
from app import db
|
||||
|
||||
|
||||
class ReceiverStats(db.Model):
|
||||
__tablename__ = "receiver_stats"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
date = db.Column(db.Date)
|
||||
|
||||
# Static data
|
||||
firstseen = db.Column(db.DateTime, index=True)
|
||||
lastseen = db.Column(db.DateTime, index=True)
|
||||
location_wkt = db.Column("location", Geometry("POINT", srid=4326))
|
||||
altitude = db.Column(db.Float(precision=2))
|
||||
version = db.Column(db.String)
|
||||
platform = db.Column(db.String)
|
||||
|
||||
# Statistic data
|
||||
aircraft_beacon_count = db.Column(db.Integer)
|
||||
aircraft_count = db.Column(db.SmallInteger)
|
||||
max_distance = db.Column(db.Float)
|
||||
quality = db.Column(db.Float(precision=2))
|
||||
|
||||
# Relation statistic data
|
||||
quality_offset = db.Column(db.Float(precision=2))
|
||||
|
||||
# Ranking data
|
||||
aircraft_beacon_count_ranking = db.Column(db.SmallInteger)
|
||||
aircraft_count_ranking = db.Column(db.SmallInteger)
|
||||
max_distance_ranking = db.Column(db.SmallInteger)
|
||||
quality_ranking = db.Column(db.Integer)
|
||||
|
||||
# Relations
|
||||
receiver_id = db.Column(db.Integer, db.ForeignKey("receivers.id", ondelete="SET NULL"), index=True)
|
||||
receiver = db.relationship("Receiver", foreign_keys=[receiver_id], backref=db.backref("stats", order_by="ReceiverStats.date.asc()"))
|
||||
|
||||
|
||||
db.Index("ix_receiver_stats_date_receiver_id", ReceiverStats.date, ReceiverStats.receiver_id)
|
|
@ -1,26 +0,0 @@
|
|||
from app import db
|
||||
|
||||
|
||||
class RelationStats(db.Model):
|
||||
__tablename__ = "relation_stats"
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
|
||||
date = db.Column(db.Date)
|
||||
|
||||
# Statistic data
|
||||
quality = db.Column(db.Float(precision=2))
|
||||
beacon_count = db.Column(db.Integer)
|
||||
|
||||
# Relations
|
||||
device_id = db.Column(db.Integer, db.ForeignKey("devices.id", ondelete="SET NULL"), index=True)
|
||||
device = db.relationship("Device", foreign_keys=[device_id], backref="relation_stats")
|
||||
receiver_id = db.Column(db.Integer, db.ForeignKey("receivers.id", ondelete="SET NULL"), index=True)
|
||||
receiver = db.relationship("Receiver", foreign_keys=[receiver_id], backref="relation_stats")
|
||||
|
||||
def __repr__(self):
|
||||
return "<RelationStats: %s,%s,%s>" % (self.date, self.quality, self.beacon_count)
|
||||
|
||||
|
||||
db.Index("ix_relation_stats_date_device_id", RelationStats.date, RelationStats.device_id, RelationStats.receiver_id)
|
||||
db.Index("ix_relation_stats_date_receiver_id", RelationStats.date, RelationStats.receiver_id, RelationStats.device_id)
|
|
@ -4,7 +4,7 @@ from app import db
|
|||
class TakeoffLanding(db.Model):
|
||||
__tablename__ = "takeoff_landings"
|
||||
|
||||
device_id = db.Column(db.Integer, db.ForeignKey("devices.id", ondelete="SET NULL"), primary_key=True)
|
||||
address = db.Column(db.String, primary_key=True)
|
||||
airport_id = db.Column(db.Integer, db.ForeignKey("airports.id", ondelete="SET NULL"), primary_key=True)
|
||||
timestamp = db.Column(db.DateTime, primary_key=True)
|
||||
|
||||
|
@ -13,4 +13,3 @@ class TakeoffLanding(db.Model):
|
|||
|
||||
# Relations
|
||||
airport = db.relationship("Airport", foreign_keys=[airport_id], backref="takeoff_landings")
|
||||
device = db.relationship("Device", foreign_keys=[device_id], backref="takeoff_landings", order_by="TakeoffLanding.timestamp")
|
||||
|
|
|
@ -1,199 +0,0 @@
|
|||
from datetime import datetime, date
|
||||
import unittest
|
||||
|
||||
from tests.base import TestBaseDB, db
|
||||
|
||||
from app.model import AircraftBeacon, ReceiverBeacon, Receiver, Device, DeviceStats
|
||||
|
||||
from app.collect.stats import create_device_stats
|
||||
|
||||
|
||||
class TestStats(TestBaseDB):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
# Prepare Beacons
|
||||
self.ab01 = AircraftBeacon(name="FLRDD4711", receiver_name="Koenigsdf", timestamp="2017-12-10 10:00:01")
|
||||
self.ab02 = AircraftBeacon(name="FLRDD4711", receiver_name="Koenigsdf", timestamp="2017-12-10 10:00:02")
|
||||
self.ab03 = AircraftBeacon(name="FLRDD4711", receiver_name="Koenigsdf", timestamp="2017-12-10 10:00:03")
|
||||
self.ab04 = AircraftBeacon(name="FLRDD4711", receiver_name="Koenigsdf", timestamp="2017-12-10 10:00:04")
|
||||
self.ab05 = AircraftBeacon(name="FLRDD4711", receiver_name="Koenigsdf", timestamp="2017-12-10 10:00:05")
|
||||
self.ab06 = AircraftBeacon(name="FLRDD4711", receiver_name="Koenigsdf", timestamp="2017-12-10 10:00:05")
|
||||
|
||||
self.rb01 = ReceiverBeacon(name="Koenigsdf", receiver_name="GLIDERN1", timestamp="2017-12-10 09:55:00", altitude=601)
|
||||
self.rb02 = ReceiverBeacon(name="Koenigsdf", receiver_name="GLIDERN1", timestamp="2017-12-10 10:00:00", altitude=601)
|
||||
self.rb03 = ReceiverBeacon(name="Koenigsdf", receiver_name="GLIDERN1", timestamp="2017-12-10 10:05:00", altitude=601)
|
||||
|
||||
self.r01 = Receiver(name="Koenigsdf")
|
||||
self.r02 = Receiver(name="Bene")
|
||||
|
||||
self.d01 = Device(address="DD4711")
|
||||
|
||||
db.session.add(self.r01)
|
||||
db.session.add(self.d01)
|
||||
db.session.commit()
|
||||
|
||||
@unittest.skip('stats will replaced by timescaledb aggregates')
|
||||
def test_create_device_stats(self):
|
||||
# Compute 1st beacon
|
||||
self.ab01.device = self.d01
|
||||
self.ab01.receiver = self.r01
|
||||
db.session.add(self.ab01)
|
||||
db.session.commit()
|
||||
|
||||
today = date(2017, 12, 10)
|
||||
create_device_stats(db.session, date=today)
|
||||
|
||||
devicestats = db.session.query(DeviceStats).all()
|
||||
self.assertEqual(len(devicestats), 1)
|
||||
self.assertEqual(devicestats[0].device, self.d01)
|
||||
|
||||
self.assertEqual(devicestats[0].max_altitude, None)
|
||||
self.assertEqual(devicestats[0].receiver_count, 1)
|
||||
self.assertEqual(devicestats[0].aircraft_beacon_count, 1)
|
||||
self.assertEqual(devicestats[0].date, datetime.strptime("2017-12-10", "%Y-%m-%d").date())
|
||||
self.assertEqual(devicestats[0].firstseen, datetime(2017, 12, 10, 10, 0, 1))
|
||||
self.assertEqual(devicestats[0].lastseen, datetime(2017, 12, 10, 10, 0, 1))
|
||||
self.assertEqual(devicestats[0].aircraft_type, None)
|
||||
self.assertEqual(devicestats[0].stealth, None)
|
||||
self.assertEqual(devicestats[0].software_version, None)
|
||||
self.assertEqual(devicestats[0].hardware_version, None)
|
||||
self.assertEqual(devicestats[0].real_address, None)
|
||||
|
||||
# Compute 2nd beacon: set altitude, aircraft_type and stealth
|
||||
self.ab02.device = self.d01
|
||||
self.ab02.receiver = self.r01
|
||||
self.ab02.altitude = 200
|
||||
self.ab02.aircraft_type = 3
|
||||
self.ab02.stealth = False
|
||||
db.session.add(self.ab02)
|
||||
db.session.commit()
|
||||
|
||||
create_device_stats(db.session, date=today)
|
||||
|
||||
devicestats = db.session.query(DeviceStats).all()
|
||||
self.assertEqual(len(devicestats), 1)
|
||||
self.assertEqual(devicestats[0].device, self.d01)
|
||||
|
||||
self.assertEqual(devicestats[0].max_altitude, 200)
|
||||
self.assertEqual(devicestats[0].receiver_count, 1)
|
||||
self.assertEqual(devicestats[0].aircraft_beacon_count, 2)
|
||||
self.assertEqual(devicestats[0].date, datetime.strptime("2017-12-10", "%Y-%m-%d").date())
|
||||
self.assertEqual(devicestats[0].firstseen, datetime(2017, 12, 10, 10, 0, 1))
|
||||
self.assertEqual(devicestats[0].lastseen, datetime(2017, 12, 10, 10, 0, 2))
|
||||
self.assertEqual(devicestats[0].aircraft_type, 3)
|
||||
self.assertEqual(devicestats[0].stealth, False)
|
||||
self.assertEqual(devicestats[0].software_version, None)
|
||||
self.assertEqual(devicestats[0].hardware_version, None)
|
||||
self.assertEqual(devicestats[0].real_address, None)
|
||||
|
||||
# Compute 3rd beacon: changed software version, but with error_count > 0
|
||||
self.ab03.device = self.d01
|
||||
self.ab03.receiver = self.r01
|
||||
self.ab03.error_count = 1
|
||||
self.ab03.software_version = 6.01
|
||||
db.session.add(self.ab03)
|
||||
db.session.commit()
|
||||
|
||||
create_device_stats(db.session, date=today)
|
||||
|
||||
devicestats = db.session.query(DeviceStats).all()
|
||||
self.assertEqual(len(devicestats), 1)
|
||||
self.assertEqual(devicestats[0].device, self.d01)
|
||||
|
||||
self.assertEqual(devicestats[0].max_altitude, 200)
|
||||
self.assertEqual(devicestats[0].receiver_count, 1)
|
||||
self.assertEqual(devicestats[0].aircraft_beacon_count, 2)
|
||||
self.assertEqual(devicestats[0].date, datetime.strptime("2017-12-10", "%Y-%m-%d").date())
|
||||
self.assertEqual(devicestats[0].firstseen, datetime(2017, 12, 10, 10, 0, 1))
|
||||
self.assertEqual(devicestats[0].lastseen, datetime(2017, 12, 10, 10, 0, 2))
|
||||
self.assertEqual(devicestats[0].aircraft_type, 3)
|
||||
self.assertEqual(devicestats[0].stealth, False)
|
||||
self.assertEqual(devicestats[0].software_version, None)
|
||||
self.assertEqual(devicestats[0].hardware_version, None)
|
||||
self.assertEqual(devicestats[0].real_address, None)
|
||||
|
||||
# Compute 4. beacon: another receiver, greater altitude, software_version, hardware_version, real_address
|
||||
self.ab04.device = self.d01
|
||||
self.ab04.receiver = self.r02
|
||||
self.ab04.altitude = 250
|
||||
self.ab04.software_version = 6.01
|
||||
self.ab04.hardware_version = 15
|
||||
self.ab04.real_address = "DDALFA"
|
||||
db.session.add(self.ab04)
|
||||
db.session.commit()
|
||||
|
||||
create_device_stats(db.session, date=today)
|
||||
|
||||
devicestats = db.session.query(DeviceStats).all()
|
||||
self.assertEqual(len(devicestats), 1)
|
||||
self.assertEqual(devicestats[0].device, self.d01)
|
||||
|
||||
self.assertEqual(devicestats[0].max_altitude, 250)
|
||||
self.assertEqual(devicestats[0].receiver_count, 2)
|
||||
self.assertEqual(devicestats[0].aircraft_beacon_count, 3)
|
||||
self.assertEqual(devicestats[0].date, datetime.strptime("2017-12-10", "%Y-%m-%d").date())
|
||||
self.assertEqual(devicestats[0].firstseen, datetime(2017, 12, 10, 10, 0, 1))
|
||||
self.assertEqual(devicestats[0].lastseen, datetime(2017, 12, 10, 10, 0, 4))
|
||||
self.assertEqual(devicestats[0].aircraft_type, 3)
|
||||
self.assertEqual(devicestats[0].stealth, False)
|
||||
self.assertEqual(devicestats[0].software_version, 6.01)
|
||||
self.assertEqual(devicestats[0].hardware_version, 15)
|
||||
self.assertEqual(devicestats[0].real_address, "DDALFA")
|
||||
|
||||
# Compute 5. beacon: lower altitude, stealth
|
||||
self.ab05.device = self.d01
|
||||
self.ab05.receiver = self.r02
|
||||
self.ab05.altitude = 100
|
||||
self.ab05.stealth = True
|
||||
db.session.add(self.ab05)
|
||||
db.session.commit()
|
||||
|
||||
create_device_stats(db.session, date=today)
|
||||
|
||||
devicestats = db.session.query(DeviceStats).all()
|
||||
self.assertEqual(len(devicestats), 1)
|
||||
self.assertEqual(devicestats[0].device, self.d01)
|
||||
|
||||
self.assertEqual(devicestats[0].max_altitude, 250)
|
||||
self.assertEqual(devicestats[0].receiver_count, 2)
|
||||
self.assertEqual(devicestats[0].aircraft_beacon_count, 4)
|
||||
self.assertEqual(devicestats[0].date, datetime.strptime("2017-12-10", "%Y-%m-%d").date())
|
||||
self.assertEqual(devicestats[0].firstseen, datetime(2017, 12, 10, 10, 0, 1))
|
||||
self.assertEqual(devicestats[0].lastseen, datetime(2017, 12, 10, 10, 0, 5))
|
||||
self.assertEqual(devicestats[0].aircraft_type, 3)
|
||||
self.assertEqual(devicestats[0].stealth, True)
|
||||
self.assertEqual(devicestats[0].software_version, 6.01)
|
||||
self.assertEqual(devicestats[0].hardware_version, 15)
|
||||
self.assertEqual(devicestats[0].real_address, "DDALFA")
|
||||
|
||||
# Compute 6. beacon: beacon from past, greater altitude, newer version
|
||||
self.ab06.device = self.d01
|
||||
self.ab06.receiver = self.r02
|
||||
self.ab06.timestamp = datetime(2017, 12, 10, 9, 59, 50)
|
||||
self.ab06.altitude = 300
|
||||
self.ab06.software_version = 6.02
|
||||
db.session.add(self.ab06)
|
||||
db.session.commit()
|
||||
|
||||
create_device_stats(db.session, date=today)
|
||||
|
||||
devicestats = db.session.query(DeviceStats).all()
|
||||
self.assertEqual(len(devicestats), 1)
|
||||
self.assertEqual(devicestats[0].device, self.d01)
|
||||
|
||||
self.assertEqual(devicestats[0].max_altitude, 300)
|
||||
self.assertEqual(devicestats[0].receiver_count, 2)
|
||||
self.assertEqual(devicestats[0].aircraft_beacon_count, 5)
|
||||
self.assertEqual(devicestats[0].date, datetime.strptime("2017-12-10", "%Y-%m-%d").date())
|
||||
self.assertEqual(devicestats[0].firstseen, datetime(2017, 12, 10, 9, 59, 50))
|
||||
self.assertEqual(devicestats[0].lastseen, datetime(2017, 12, 10, 10, 0, 5))
|
||||
self.assertEqual(devicestats[0].aircraft_type, 3)
|
||||
self.assertEqual(devicestats[0].stealth, True)
|
||||
self.assertEqual(devicestats[0].software_version, 6.01)
|
||||
self.assertEqual(devicestats[0].hardware_version, 15)
|
||||
self.assertEqual(devicestats[0].real_address, "DDALFA")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
Ładowanie…
Reference in New Issue