diff --git a/README.md b/README.md index fa7ae5b..61cc869 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,7 @@ available commands: [stats] create Create DeviceStats, ReceiverStats and RelationStats. + create_ognrange Create stats for Melissa's ognrange. update_devices Update devices with data from stats. update_receivers Update receivers with data from stats. ``` diff --git a/ogn/backend/ognrange.py b/ogn/backend/ognrange.py index b499652..870bbc4 100644 --- a/ogn/backend/ognrange.py +++ b/ogn/backend/ognrange.py @@ -7,9 +7,10 @@ from ogn.model import Receiver def alchemyencoder(obj): + """JSON encoder function for SQLAlchemy special classes.""" + import decimal from datetime import datetime - """JSON encoder function for SQLAlchemy special classes.""" if isinstance(obj, datetime): return obj.strftime('%Y-%m-%d %H:%M') elif isinstance(obj, decimal.Decimal): diff --git a/ogn/collect/ognrange.py b/ogn/collect/ognrange.py index 7d8b7ac..1b87b05 100644 --- a/ogn/collect/ognrange.py +++ b/ogn/collect/ognrange.py @@ -1,24 +1,31 @@ from celery.utils.log import get_task_logger from sqlalchemy import String -from sqlalchemy import and_, insert, update, exists +from sqlalchemy import and_, insert, update, exists, between from sqlalchemy.sql import func, null from ogn.collect.celery import app from ogn.model import AircraftBeacon, ReceiverCoverage +from ogn.utils import date_to_timestamps logger = get_task_logger(__name__) @app.task -def update_receiver_coverage(session=None): - """Add/update receiver coverages.""" +def create_receiver_coverage(session=None, date=None): + """Create receiver coverages.""" logger.info("Compute receiver coverages.") if session is None: session = app.session + if not date: + logger.warn("A date is needed for calculating stats. Exiting") + return None + else: + (start, end) = date_to_timestamps(date) + # Filter aircraft beacons and shrink precision of MGRS from 1m to 1km resolution: 30UXC 00061 18429 -> 30UXC 00 18 sq = session.query((func.left(AircraftBeacon.location_mgrs, 5, type_=String) + func.substring(AircraftBeacon.location_mgrs, 6, 2, type_=String) + func.substring(AircraftBeacon.location_mgrs, 11, 2, type_=String)).label('reduced_mgrs'), AircraftBeacon.receiver_id, @@ -26,7 +33,8 @@ def update_receiver_coverage(session=None): AircraftBeacon.signal_quality, AircraftBeacon.altitude, AircraftBeacon.device_id) \ - .filter(and_(AircraftBeacon.location_mgrs != null(), + .filter(and_(between(AircraftBeacon.timestamp, start, end), + AircraftBeacon.location_mgrs != null(), AircraftBeacon.receiver_id != null(), AircraftBeacon.device_id != null())) \ .subquery() diff --git a/ogn/commands/stats.py b/ogn/commands/stats.py index 42b4c6d..fc15a64 100644 --- a/ogn/commands/stats.py +++ b/ogn/commands/stats.py @@ -8,6 +8,8 @@ from ogn.collect.stats import create_device_stats, create_receiver_stats, create update_qualities, update_receivers as update_receivers_command, update_devices as update_devices_command,\ update_device_stats_jumps +from ogn.collect.ognrange import create_receiver_coverage + manager = Manager() @@ -41,3 +43,15 @@ def update_devices(): result = update_devices_command(session=session) print(result) + + +@manager.command +def create_ognrange(start=None, end=None): + """Create stats for Melissas ognrange.""" + + days = get_database_days(start, end) + + pbar = tqdm(days) + for single_date in pbar: + pbar.set_description(datetime.strftime(single_date, '%Y-%m-%d')) + result = create_receiver_coverage(session=session, date=single_date) \ No newline at end of file diff --git a/ogn/model/receiver_coverage.py b/ogn/model/receiver_coverage.py index b98c90e..20f345a 100644 --- a/ogn/model/receiver_coverage.py +++ b/ogn/model/receiver_coverage.py @@ -9,7 +9,6 @@ class ReceiverCoverage(Base): __tablename__ = "receiver_coverages" location_mgrs = Column(String(9), primary_key=True) - receiver_id = Column(Integer, ForeignKey('receivers.id', ondelete='SET NULL'), primary_key=True) date = Column(Date, primary_key=True) max_signal_quality = Column(Float) @@ -20,5 +19,5 @@ class ReceiverCoverage(Base): device_count = Column(SmallInteger) # Relations - receiver_id = Column(Integer, ForeignKey('receivers.id', ondelete='SET NULL'), index=True) + receiver_id = Column(Integer, ForeignKey('receivers.id', ondelete='SET NULL'), primary_key=True) receiver = relationship('Receiver', foreign_keys=[receiver_id], backref=backref('receiver_coverages', order_by='ReceiverCoverage.date.asc()')) diff --git a/tests/collect/test_ognrange.py b/tests/collect/test_ognrange.py index b642722..b7ddd11 100644 --- a/tests/collect/test_ognrange.py +++ b/tests/collect/test_ognrange.py @@ -1,8 +1,9 @@ import unittest import os +from datetime import date from ogn.model import AircraftBeacon, Receiver, ReceiverCoverage, Device -from ogn.collect.ognrange import update_receiver_coverage +from ogn.collect.ognrange import create_receiver_coverage class TestDB(unittest.TestCase): @@ -51,7 +52,7 @@ class TestDB(unittest.TestCase): def test_update_receiver_coverage(self): session = self.session - update_receiver_coverage(session) + create_receiver_coverage(session, date=date(2017, 12, 10)) coverages = session.query(ReceiverCoverage).all() self.assertEqual(len(coverages), 1)