pull/68/head
Konstantin Gründger 2017-12-29 16:30:50 +01:00
rodzic 7729dca315
commit 3b78f0b97d
6 zmienionych plików z 71 dodań i 40 usunięć

Wyświetl plik

@ -1,9 +1,20 @@
from datetime import datetime, timedelta, date
import os
from datetime import datetime, timedelta, timezone, date
from sqlalchemy import func, and_, between, case, null
from sqlalchemy import func, and_, between, case
from ogn.model import AircraftBeacon, DeviceInfo, Device, Receiver
from ogn.model import AircraftBeacon, Device, Receiver
def utc_to_local(utc_dt):
return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None)
def encode(address):
return 'xx' + address
def decode(code):
return code[2:9]
def rec(session):
@ -34,28 +45,25 @@ def lxml(session, show_offline=False, lat_max=90, lat_min=-90, lon_max=180, lon_
else:
observation_start = datetime.utcnow() - timedelta(minutes=5)
position_query = session.query(Device, AircraftBeacon, DeviceInfo) \
position_query = session.query(AircraftBeacon, Device) \
.filter(and_(between(func.ST_Y(AircraftBeacon.location_wkt), lat_min, lat_max),
between(func.ST_X(AircraftBeacon.location_wkt), lon_min, lon_max))) \
.filter(Device.lastseen > observation_start) \
.filter(Device.last_position_beacon_id == AircraftBeacon.id) \
.outerjoin(DeviceInfo, DeviceInfo.device_id == Device.id)
.filter(Device.lastseen == AircraftBeacon.timestamp) \
.filter(Device.id == AircraftBeacon.device_id)
lines = list()
lines.append('<?xml version="1.0" encoding="UTF-8"?>')
lines.append('<markers>')
for [aircraft_beacon, device_info] in position_query.all():
if device_info and (not device_info.tracked or not device_info.identified):
continue
for [aircraft_beacon, device] in position_query.all():
code = encode(device.address)
code = encode(aircraft_beacon.address)
if len(device.informations) > 0:
device_info = device.informations[0]
if device_info and (not device_info.tracked or not device_info.identified):
continue
if device_info is None:
competition = ('_' + code[-2:]).lower()
registration = code
address = 0
else:
if not device_info.competition:
competition = device_info.registration[-2:]
else:
@ -66,12 +74,18 @@ def lxml(session, show_offline=False, lat_max=90, lat_min=-90, lon_max=180, lon_
else:
registration = device_info.registration
address = device_info.address
address = device.address
else:
device_info = None
competition = ('_' + code[-2:]).lower()
registration = code
address = 0
elapsed_time = datetime.utcnow() - aircraft_beacon.timestamp
elapsed_seconds = int(elapsed_time.total_seconds())
lines.append('<m a="{0:.7f},{1:.7f},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13}"/>'
lines.append(' <m a="{0:.7f},{1:.7f},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13}"/>'
.format(aircraft_beacon.location.latitude,
aircraft_beacon.location.longitude,
competition,
@ -81,7 +95,7 @@ def lxml(session, show_offline=False, lat_max=90, lat_min=-90, lon_max=180, lon_
elapsed_seconds,
int(aircraft_beacon.track),
int(aircraft_beacon.ground_speed),
int(aircraft_beacon.climb_rate*10)/10,
int(aircraft_beacon.climb_rate * 10) / 10,
aircraft_beacon.aircraft_type,
aircraft_beacon.receiver_name,
address,

Wyświetl plik

@ -21,8 +21,8 @@ def stations2_filtered_pl(session):
query = session.query(
Receiver.name.label('s'),
label('lt', func.round(func.ST_Y(Receiver.location_wkt)*10000)/10000),
label('lg', func.round(func.ST_X(Receiver.location_wkt)*10000)/10000),
label('lt', func.round(func.ST_Y(Receiver.location_wkt) * 10000) / 10000),
label('lg', func.round(func.ST_X(Receiver.location_wkt) * 10000) / 10000),
case([(Receiver.lastseen > last_10_minutes, "U")],
else_="D").label('u'),
Receiver.lastseen.label('ut'),
@ -30,6 +30,6 @@ def stations2_filtered_pl(session):
.order_by(Receiver.lastseen)
res = session.execute(query)
stations = json.dumps({"stations": [dict(r) for r in res]}, default=alchemyencoder)
stations = json.dumps({'stations': [dict(r) for r in res]}, default=alchemyencoder)
return stations

Wyświetl plik

@ -19,6 +19,7 @@ class Device(Base):
# Relations
aircraft_beacons = relationship('AircraftBeacon')
informations = relationship('DeviceInfo', backref="device")
def __repr__(self):
return "<Device: %s,%s,%s,%s,%s,%s>" % (

Wyświetl plik

@ -21,7 +21,6 @@ class DeviceInfo(Base):
# Relations
device_id = Column(Integer, ForeignKey('device.id', ondelete='SET NULL'), index=True)
device = relationship('Device', foreign_keys=[device_id])
def __repr__(self):
return "<DeviceInfo: %s,%s,%s,%s,%s,%s,%s,%s,%s>" % (

Wyświetl plik

Wyświetl plik

@ -5,10 +5,11 @@ from datetime import datetime
from xmlunittest import XmlTestMixin
from ogn.model import Receiver, Device
from ogn.model import AircraftBeacon, Receiver, Device, DeviceInfo
from ogn.backend.liveglidernet import rec, lxml
from ogn.backend.ognrange import stations2_filtered_pl
from ogn.model.aircraft_type import AircraftType
class TestDB(unittest.TestCase, XmlTestMixin):
@ -29,21 +30,37 @@ class TestDB(unittest.TestCase, XmlTestMixin):
self.r01 = Receiver(name='Koenigsdf', location_wkt='0101000020E610000061E8FED7A6EE26407F20661C10EA4740', lastseen='2017-12-20 10:00:00', altitude=601, version='0.2.5', platform='ARM')
self.r02 = Receiver(name='Bene', location_wkt='0101000020E6100000D5E76A2BF6C72640D4063A6DA0DB4740', lastseen='2017-12-20 09:45:00', altitude=609, version='0.2.7', platform='x64')
self.r03 = Receiver(name='Ohlstadt', location_wkt='0101000020E6100000057E678EBF772640A142883E32D44740', lastseen='2017-12-20 10:05:00', altitude=655, version='0.2.6', platform='ARM')
self.d01 = Device(address='DD4711')
self.d02 = Device(address='DD0815')
session.add(self.r01)
session.add(self.r02)
session.add(self.r03)
session.commit()
self.d01 = Device(address='DD4711', lastseen='2017-12-20 10:00:02')
self.d02 = Device(address='DD0815', lastseen='2017-12-20 09:56:00')
session.add(self.d01)
session.add(self.d02)
session.commit()
self.di01 = DeviceInfo(registration='D-4711', competition='Hi', tracked=True, identified=True, device_id=self.d01.id)
session.add(self.di01)
session.commit()
self.ab11 = AircraftBeacon(location_wkt='0101000020E6100000211FF46C56ED26402650D7EDC6E94740', aircraft_type=AircraftType.glider_or_motor_glider, receiver_name='Koenigsdf', timestamp='2017-12-20 10:00:01', track=105, ground_speed=57, climb_rate=-0.5, device_id=self.d01.id)
self.ab12 = AircraftBeacon(location_wkt='0101000020E6100000806DEA295FED2640347D898BB6E94740', aircraft_type=AircraftType.glider_or_motor_glider, receiver_name='Koenigsdf', timestamp='2017-12-20 10:00:02', track=123, ground_speed=55, climb_rate=-0.4, altitude=209, device_id=self.d01.id)
self.ab21 = AircraftBeacon(location_wkt='0101000020E6100000F38B25BF58F22640448B6CE7FBE94740', aircraft_type=AircraftType.powered_aircraft, receiver_name='Koenigsdf', timestamp='2017-12-20 09:54:30', track=280, ground_speed=80, climb_rate=-2.9, device_id=self.d02.id)
self.ab22 = AircraftBeacon(location_wkt='0101000020E6100000A5E8482EFFF12640DC1EAA16FEE94740', aircraft_type=AircraftType.powered_aircraft, receiver_name='Bene', timestamp='2017-12-20 09:56:00', track=270, ground_speed=77, climb_rate=-1.5, altitude=543, device_id=self.d02.id)
session.add(self.ab11)
session.add(self.ab12)
session.add(self.ab21)
session.add(self.ab22)
session.commit()
def tearDown(self):
session = self.session
session.execute("DELETE FROM device_info")
session.execute("DELETE FROM receiver")
session.execute("DELETE FROM device")
session.execute("DELETE FROM aircraft_beacon")
session.commit()
@mock.patch('ogn.backend.liveglidernet.datetime')
@ -59,6 +76,7 @@ class TestDB(unittest.TestCase, XmlTestMixin):
self.assertXmlNode(root, tag='markers')
self.assertXpathsOnlyOne(root, ('./m[@a="Koenigsdf"]', './m[@a="Bene"]', './m[@a="Ohlstadt"]'))
# Check the complete document
expected = """<?xml version="1.0" encoding="UTF-8"?>
<markers>
<m e="0"/>
@ -68,26 +86,26 @@ class TestDB(unittest.TestCase, XmlTestMixin):
</markers>
""".encode(encoding='utf-8')
# Check the complete document
self.assertXmlEquivalentOutputs(data, expected)
print(data)
@unittest.skip("not finished yet")
@mock.patch('ogn.backend.liveglidernet.utc_to_local', side_effect=lambda x: x)
@mock.patch('ogn.backend.liveglidernet.datetime')
def test_lxml(self, datetime_mock):
def test_lxml(self, datetime_mock, utc_to_local_mock):
session = self.session
datetime_mock.utcnow.return_value = datetime(2017, 12, 20, 10, 0)
datetime_mock.utcnow.return_value = datetime(2017, 12, 20, 10, 0, 5)
data = lxml(session).encode(encoding='utf-8')
# Check the document
root = self.assertXmlDocument(data)
self.assertXmlNode(root, tag='markers')
self.assertXpathsOnlyOne(root, ('./m[@a="Koenigsdf"]', './m[@a="Bene"]', './m[@a="Ohlstadt"]'))
# Check the complete document
expected = """<?xml version="1.0" encoding="UTF-8"?>
<markers>
<m a="47.8258833,11.4636167,Hi,D-4711,209,10:00:02,3,123,55,-0.4,1,Koenigsdf,DD4711,xxDD4711"/>
<m a="47.8280667,11.4726500,_15,xxDD0815,543,09:56:00,245,270,77,-1.5,8,Bene,0,xxDD0815"/>
</markers>
""".encode(encoding='utf-8')
print(data)
self.assertXmlEquivalentOutputs(data, expected)
@mock.patch('ogn.backend.ognrange.datetime')
def test_stations2_filtered_pl(self, datetime_mock):
@ -98,7 +116,6 @@ class TestDB(unittest.TestCase, XmlTestMixin):
import json
result = stations2_filtered_pl(session)
print(result)
data = json.loads(result)