Загрузил файл
This commit is contained in:
parent
1150f86738
commit
1ca82df0ae
|
|
@ -0,0 +1,50 @@
|
|||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class Marker(Model):
|
||||
"""Marker represents the marker that each visible packet has, two packet with the same marker id will be connected on map
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.id = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return True
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Since packet will be inserted in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (not self.isExistingObject()):
|
||||
cursor = self.db.cursor()
|
||||
cursor.execute("""select nextval('marker_seq')""")
|
||||
self.id = cursor.fetchone()[0]
|
||||
cursor.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Since packet will be updated in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class OgnDevice(Model):
|
||||
"""OgnDevice represents a pre registered device in the ogn ddb
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
|
||||
self.deviceType = None
|
||||
self.deviceId = None
|
||||
self.aircraftModel = None
|
||||
self.registration = None
|
||||
self.cn = None
|
||||
self.tracked = None
|
||||
self.identified = None
|
||||
self.ddbAircraftType = None # Do not confuse with the aircraft type in aprs message
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return True
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def getDict(self):
|
||||
"""Returns a dict representation of the object
|
||||
|
||||
Returns:
|
||||
Dict representation of the object
|
||||
"""
|
||||
data = {}
|
||||
|
||||
data['device_type'] = self.deviceType
|
||||
data['device_id'] = self.deviceId
|
||||
data['aircraft_model'] = self.aircraftModel
|
||||
data['registration'] = self.registration
|
||||
data['cn'] = self.cn
|
||||
data['tracked'] = self.tracked
|
||||
data['identified'] = self.identified
|
||||
data['ddb_aircraft_type'] = self.ddbAircraftType
|
||||
|
||||
return data
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class OgnHiddenStation(Model):
|
||||
"""OgnDevice represents a pre registered device in the ogn ddb
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
|
||||
self.id = None
|
||||
self.hashedName = None
|
||||
|
||||
def getStationName(self):
|
||||
"""Returns the unidentifiable station name used for the current hashed name
|
||||
|
||||
Returns:
|
||||
string
|
||||
"""
|
||||
if (self.isExistingObject()):
|
||||
return 'UNKNOWN' + str(self.id)
|
||||
else:
|
||||
return None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return True
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Since packet will be inserted in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (not self.isExistingObject()):
|
||||
insertCursor = self.db.cursor()
|
||||
insertCursor.execute(
|
||||
"""insert into ogn_hidden_station(hashed_name) values(%s) RETURNING id""", (str(
|
||||
self.hashedName).strip(),)
|
||||
)
|
||||
self.id = insertCursor.fetchone()[0]
|
||||
insertCursor.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
|
@ -0,0 +1,359 @@
|
|||
import logging
|
||||
import re
|
||||
from twisted.python import log
|
||||
import json
|
||||
import datetime
|
||||
import time
|
||||
from math import sin, cos, sqrt, atan2, radians, floor, ceil
|
||||
|
||||
from trackdirect.common.Model import Model
|
||||
from trackdirect.repositories.StationRepository import StationRepository
|
||||
from trackdirect.repositories.SenderRepository import SenderRepository
|
||||
from trackdirect.objects.Station import Station
|
||||
|
||||
from trackdirect.exceptions.TrackDirectMissingSenderError import TrackDirectMissingSenderError
|
||||
from trackdirect.exceptions.TrackDirectMissingStationError import TrackDirectMissingStationError
|
||||
|
||||
|
||||
class Packet(Model):
|
||||
"""Packet represents a APRS packet, AIS packet or any other supported packet
|
||||
|
||||
Note:
|
||||
Packet corresponds to a row in the packetYYYYMMDD table
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.logger = logging.getLogger('trackdirect')
|
||||
|
||||
self.id = None
|
||||
self.stationId = None
|
||||
self.senderId = None
|
||||
self.packetTypeId = None
|
||||
self.timestamp = None
|
||||
self.reportedTimestamp = None
|
||||
self.positionTimestamp = None # Inherited from prev packet if position was equal
|
||||
self.latitude = None
|
||||
self.longitude = None
|
||||
self.symbol = None
|
||||
self.symbolTable = None
|
||||
self.markerId = None
|
||||
self.markerCounter = None
|
||||
self.markerPrevPacketTimestamp = None
|
||||
self.mapId = None
|
||||
self.sourceId = None
|
||||
self.mapSector = None
|
||||
self.relatedMapSectors = []
|
||||
self.speed = None
|
||||
self.course = None
|
||||
self.altitude = None
|
||||
self.rng = None
|
||||
self.phg = None
|
||||
self.latestRngTimestamp = None
|
||||
self.latestPhgTimestamp = None
|
||||
self.comment = None
|
||||
self.rawPath = None
|
||||
self.raw = None
|
||||
|
||||
# packet tail timestamp indicates how long time ago we had a tail
|
||||
self.packetTailTimestamp = None
|
||||
|
||||
# If packet reports a new position for a moving symbol is_moving will be 1 otherwise 0
|
||||
# Some times is_moving will be 0 for a moving symbol, but as fast we realize it is moving related packets will have is_moving set to 1
|
||||
self.isMoving = 1
|
||||
|
||||
self.posambiguity = None
|
||||
|
||||
# Following attributes will not allways be loaded from database (comes from related tables)
|
||||
self.stationIdPath = []
|
||||
self.stationNamePath = []
|
||||
self.stationLocationPath = []
|
||||
|
||||
# Will only be used when packet is not inserted to database yet
|
||||
self.replacePacketId = None
|
||||
self.replacePacketTimestamp = None
|
||||
self.abnormalPacketId = None
|
||||
self.abnormalPacketTimestamp = None
|
||||
self.confirmPacketId = None
|
||||
self.confirmPacketTimestamp = None
|
||||
|
||||
# Will only be used when packet is not inserted to database yet
|
||||
self.ogn = None
|
||||
self.weather = None
|
||||
self.telemetry = None
|
||||
self.stationTelemetryBits = None
|
||||
self.stationTelemetryEqns = None
|
||||
self.stationTelemetryParam = None
|
||||
self.stationTelemetryUnit = None
|
||||
self.senderName = None
|
||||
self.stationName = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return True
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Since packet will be inserted in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Since packet will be updated in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def getDistance(self, p2Lat, p2Lng):
|
||||
"""Get distance in meters between current position and specified position
|
||||
|
||||
Args:
|
||||
p2Lat (float): Position 2 latitude
|
||||
p2Lng (float): Position 2 longitude
|
||||
|
||||
Returns:
|
||||
Distance in meters between the two specified positions (as float)
|
||||
"""
|
||||
if (self.latitude is not None
|
||||
and self.longitude is not None):
|
||||
p1Lat = self.latitude
|
||||
p1Lng = self.longitude
|
||||
R = 6378137 # Earths mean radius in meter
|
||||
dLat = radians(p2Lat - p1Lat)
|
||||
dLong = radians(p2Lng - p1Lng)
|
||||
a = sin(dLat / 2) * sin(dLat / 2) + cos(radians(p1Lat)) * \
|
||||
cos(radians(p2Lat)) * sin(dLong / 2) * sin(dLong / 2)
|
||||
c = 2 * atan2(sqrt(a), sqrt(1 - a))
|
||||
d = R * c
|
||||
return d # returns the distance in meter
|
||||
else:
|
||||
return None
|
||||
|
||||
def getCalculatedSpeed(self, prevPacket):
|
||||
"""Get speed compared to previous packet position and timestamp
|
||||
|
||||
Args:
|
||||
prevPacket (Packet): Previous related packet for the same station
|
||||
|
||||
Returns:
|
||||
Speed in kmh compared to previous packet position and timestamp (as float)
|
||||
"""
|
||||
if (self.latitude is not None
|
||||
and self.longitude is not None):
|
||||
distance = self.getDistance(
|
||||
prevPacket.latitude, prevPacket.longitude)
|
||||
time = abs(prevPacket.timestamp - self.timestamp)
|
||||
if (self.reportedTimestamp is not None
|
||||
and prevPacket.reportedTimestamp is not None
|
||||
and self.reportedTimestamp != 0
|
||||
and prevPacket.reportedTimestamp != 0
|
||||
and (self.reportedTimestamp % 60 != 0 or prevPacket.reportedTimestamp % 60 != 0)
|
||||
and prevPacket.reportedTimestamp != self.reportedTimestamp):
|
||||
time = abs(prevPacket.reportedTimestamp -
|
||||
self.reportedTimestamp)
|
||||
|
||||
if (time == 0):
|
||||
return 0
|
||||
return distance / time # meters per second
|
||||
else:
|
||||
return None
|
||||
|
||||
def isSymbolEqual(self, comparePacket):
|
||||
"""Returns true if current symbol is equal to symbol in specified packet
|
||||
|
||||
Args:
|
||||
comparePacket (Packet): Packet to compare current symbol with
|
||||
|
||||
Returns:
|
||||
True if current symbol is equal to symbol in specified packet
|
||||
"""
|
||||
if (self.symbol is not None
|
||||
and self.symbolTable is not None
|
||||
and comparePacket.symbol is not None
|
||||
and comparePacket.symbolTable is not None
|
||||
and self.symbol == comparePacket.symbol
|
||||
and self.symbolTable == comparePacket.symbolTable):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def isPostitionEqual(self, comparePacket):
|
||||
"""Returns true if current position is equal to position in specified packet
|
||||
|
||||
Args:
|
||||
comparePacket (Packet): Packet to compare current position with
|
||||
|
||||
Returns:
|
||||
True if current position is equal to position in specified packet
|
||||
"""
|
||||
if (comparePacket.latitude is not None
|
||||
and comparePacket.longitude is not None
|
||||
and self.longitude is not None
|
||||
and self.latitude is not None
|
||||
and round(self.latitude, 5) == round(comparePacket.latitude, 5)
|
||||
and round(self.longitude, 5) == round(comparePacket.longitude, 5)):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def getTransmitDistance(self):
|
||||
"""Calculate the transmit distance
|
||||
|
||||
Notes:
|
||||
require that stationLocationPath is set
|
||||
|
||||
Args:
|
||||
None
|
||||
|
||||
Returns:
|
||||
Distance in meters for this transmission
|
||||
"""
|
||||
if (self.stationLocationPath is None
|
||||
or len(self.stationLocationPath) < 1):
|
||||
return None
|
||||
|
||||
location = self.stationLocationPath[0]
|
||||
if (location[0] is None
|
||||
or location[1] is None):
|
||||
return None
|
||||
|
||||
if (self.latitude is not None
|
||||
and self.longitude is not None):
|
||||
|
||||
# Current packet contains position, use that
|
||||
return self.getDistance(location[0], location[1])
|
||||
else:
|
||||
|
||||
# Current packet is missing position, use latest station position
|
||||
stationRepository = StationRepository(self.db)
|
||||
station = stationRepository.getObjectById(self.stationId)
|
||||
if (not station.isExistingObject()):
|
||||
return None
|
||||
|
||||
if (station.latestConfirmedLatitude is not None and station.latestConfirmedLongitude is not None):
|
||||
curStationLatestLocationPacket = Packet(self.db)
|
||||
curStationLatestLocationPacket.latitude = station.latestConfirmedLatitude
|
||||
curStationLatestLocationPacket.longitude = station.latestConfirmedLongitude
|
||||
return curStationLatestLocationPacket.getDistance(location[0], location[1])
|
||||
else:
|
||||
return None
|
||||
|
||||
def getDict(self, includeStationName=False):
|
||||
"""Returns a dict representation of the object
|
||||
|
||||
Args:
|
||||
includeStationName (Boolean): Include station name and sender name in dict
|
||||
|
||||
Returns:
|
||||
Dict representation of the object
|
||||
"""
|
||||
data = {}
|
||||
data['id'] = self.id
|
||||
|
||||
if (self.stationId is not None):
|
||||
data['station_id'] = int(self.stationId)
|
||||
else:
|
||||
data['station_id'] = None
|
||||
|
||||
if (self.senderId is not None):
|
||||
data['sender_id'] = int(self.senderId)
|
||||
else:
|
||||
data['sender_id'] = None
|
||||
|
||||
data['packet_type_id'] = self.packetTypeId
|
||||
data['timestamp'] = self.timestamp
|
||||
data['reported_timestamp'] = self.reportedTimestamp
|
||||
data['position_timestamp'] = self.positionTimestamp
|
||||
|
||||
if (self.latitude is not None and self.longitude is not None):
|
||||
data['latitude'] = float(self.latitude)
|
||||
data['longitude'] = float(self.longitude)
|
||||
else:
|
||||
data['latitude'] = None
|
||||
data['longitude'] = None
|
||||
|
||||
data['symbol'] = self.symbol
|
||||
data['symbol_table'] = self.symbolTable
|
||||
data['marker_id'] = self.markerId
|
||||
data['marker_counter'] = self.markerCounter
|
||||
data['map_id'] = self.mapId
|
||||
data['source_id'] = self.sourceId
|
||||
data['map_sector'] = self.mapSector
|
||||
data['related_map_sectors'] = self.relatedMapSectors
|
||||
data['speed'] = self.speed
|
||||
data['course'] = self.course
|
||||
data['altitude'] = self.altitude
|
||||
data['rng'] = self.rng
|
||||
data['phg'] = self.phg
|
||||
data['latest_phg_timestamp'] = self.latestPhgTimestamp
|
||||
data['latest_rng_timestamp'] = self.latestRngTimestamp
|
||||
data['comment'] = self.comment
|
||||
data['raw_path'] = self.rawPath
|
||||
data['raw'] = self.raw
|
||||
data['packet_tail_timestamp'] = self.packetTailTimestamp
|
||||
data['is_moving'] = self.isMoving
|
||||
data['posambiguity'] = self.posambiguity
|
||||
data['db'] = 1
|
||||
|
||||
if (includeStationName):
|
||||
try:
|
||||
stationRepository = StationRepository(self.db)
|
||||
station = stationRepository.getCachedObjectById(
|
||||
data['station_id'])
|
||||
data['station_name'] = station.name
|
||||
except TrackDirectMissingStationError as e:
|
||||
data['station_name'] = ''
|
||||
|
||||
try:
|
||||
senderRepository = SenderRepository(self.db)
|
||||
sender = senderRepository.getCachedObjectById(
|
||||
data['sender_id'])
|
||||
data['sender_name'] = sender.name
|
||||
except TrackDirectMissingSenderError as e:
|
||||
data['sender_name'] = ''
|
||||
|
||||
data['station_id_path'] = self.stationIdPath
|
||||
data['station_name_path'] = self.stationNamePath
|
||||
data['station_location_path'] = self.stationLocationPath
|
||||
data['telemetry'] = None
|
||||
if (self.telemetry is not None):
|
||||
data['telemetry'] = self.telemetry.getDict()
|
||||
data['weather'] = None
|
||||
if (self.weather is not None):
|
||||
data['weather'] = self.weather.getDict()
|
||||
data['ogn'] = None
|
||||
if (self.ogn is not None):
|
||||
data['ogn'] = self.ogn.getDict()
|
||||
return data
|
||||
|
||||
def getJson(self):
|
||||
"""Returns a json representation of the object
|
||||
|
||||
Returns:
|
||||
Json representation of the object (returnes None on failure)
|
||||
"""
|
||||
data = self.getDict()
|
||||
|
||||
try:
|
||||
return json.dumps(data, ensure_ascii=False).encode('utf8')
|
||||
except (ValueError) as exp:
|
||||
self.logger.error(e, exc_info=1)
|
||||
|
||||
return None
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class PacketOgn(Model):
|
||||
"""PacketOgn represents the OGN data in a APRS packet
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.id = None
|
||||
self.packetId = None
|
||||
self.stationId = None
|
||||
self.timestamp = None
|
||||
self.ognSenderAddress = None
|
||||
self.ognAddressTypeId = None
|
||||
self.ognAircraftTypeId = None
|
||||
self.ognClimbRate = None
|
||||
self.ognTurnRate = None
|
||||
self.ognSignalToNoiseRatio = None
|
||||
self.ognBitErrorsCorrected = None
|
||||
self.ognFrequencyOffset = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (self.stationId <= 0):
|
||||
return False
|
||||
|
||||
if (self.packetId <= 0):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Since packet will be inserted in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Since packet will be updated in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def getDict(self):
|
||||
"""Returns the packet OGN as a dict
|
||||
|
||||
Args:
|
||||
None
|
||||
|
||||
Returns:
|
||||
A packet OGN dict
|
||||
"""
|
||||
data = {}
|
||||
data['id'] = self.id
|
||||
data['packet_id'] = self.packetId
|
||||
data['station_id'] = self.stationId
|
||||
data['timestamp'] = self.timestamp
|
||||
data['ogn_sender_address'] = self.ognSenderAddress
|
||||
data['ogn_address_type_id'] = self.ognAddressTypeId
|
||||
data['ogn_aircraft_type_id'] = self.ognAircraftTypeId
|
||||
data['ogn_climb_rate'] = self.ognClimbRate
|
||||
data['ogn_turn_rate'] = self.ognTurnRate
|
||||
data['ogn_signal_to_noise_ratio'] = self.ognSignalToNoiseRatio
|
||||
data['ogn_bit_errors_corrected'] = self.ognBitErrorsCorrected
|
||||
data['ogn_frequency_offset'] = self.ognFrequencyOffset
|
||||
return data
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
from trackdirect.common.Model import Model
|
||||
from trackdirect.database.PacketTelemetryTableCreator import PacketTelemetryTableCreator
|
||||
|
||||
|
||||
class PacketTelemetry(Model):
|
||||
"""PacketTelemetry represents the telemetry data in a APRS packet
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.id = None
|
||||
self.packetId = None
|
||||
self.stationId = None
|
||||
self.timestamp = None
|
||||
self.val1 = None
|
||||
self.val2 = None
|
||||
self.val3 = None
|
||||
self.val4 = None
|
||||
self.val5 = None
|
||||
self.bits = None
|
||||
self.seq = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (self.stationId <= 0):
|
||||
return False
|
||||
|
||||
if (self.packetId <= 0):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Since packet will be inserted in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Since packet will be updated in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def isDuplicate(self):
|
||||
"""Method returnes true if a duplicate exists in database
|
||||
|
||||
Returns:
|
||||
True if a duplicate exists in database otherwise False
|
||||
"""
|
||||
packetTelemetryTableCreator = PacketTelemetryTableCreator(self.db)
|
||||
packetTelemetryTableCreator.disableCreateIfMissing()
|
||||
packetTelemetryTable = packetTelemetryTableCreator.getPacketTelemetryTable(
|
||||
self.timestamp)
|
||||
if (packetTelemetryTable is not None):
|
||||
|
||||
selectCursor = self.db.cursor()
|
||||
selectCursor.execute("""select * from """ + packetTelemetryTable +
|
||||
""" where station_id = %s order by timestamp desc limit 1""", (self.stationId,))
|
||||
|
||||
record = selectCursor.fetchone()
|
||||
selectCursor.close()
|
||||
if record is not None and record['seq'] == self.seq:
|
||||
return True
|
||||
return False
|
||||
|
||||
def getDict(self):
|
||||
"""Returns a packet telemetry dict
|
||||
|
||||
Args:
|
||||
None
|
||||
|
||||
Returns:
|
||||
A packet telemetry dict
|
||||
"""
|
||||
data = {}
|
||||
data['id'] = self.id
|
||||
data['packet_id'] = self.packetId
|
||||
data['station_id'] = self.stationId
|
||||
data['timestamp'] = self.timestamp
|
||||
data['val1'] = self.val1
|
||||
data['val2'] = self.val2
|
||||
data['val3'] = self.val3
|
||||
data['val4'] = self.val4
|
||||
data['val5'] = self.val5
|
||||
data['bits'] = self.bits
|
||||
data['seq'] = self.seq
|
||||
return data
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class PacketWeather(Model):
|
||||
"""PacketWeather represents the weather data in a APRS packet
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.id = None
|
||||
self.packetId = None
|
||||
self.stationId = None
|
||||
self.timestamp = None
|
||||
self.humidity = None
|
||||
self.pressure = None
|
||||
self.rain1h = None
|
||||
self.rain24h = None
|
||||
self.rainSinceMidnight = None
|
||||
self.temperature = None
|
||||
self.windDirection = None
|
||||
self.windGust = None
|
||||
self.windSpeed = None
|
||||
self.luminosity = None
|
||||
self.snow = None
|
||||
self.wxRawTimestamp = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (self.stationId <= 0):
|
||||
return False
|
||||
|
||||
if (self.packetId <= 0):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Since packet will be inserted in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Since packet will be updated in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
||||
def getDict(self):
|
||||
"""Returns the packet weather as a dict
|
||||
|
||||
Args:
|
||||
None
|
||||
|
||||
Returns:
|
||||
A packet weather dict
|
||||
"""
|
||||
data = {}
|
||||
data['id'] = self.id
|
||||
data['packet_id'] = self.packetId
|
||||
data['station_id'] = self.stationId
|
||||
data['timestamp'] = self.timestamp
|
||||
data['humidity'] = self.humidity
|
||||
data['pressure'] = self.pressure
|
||||
data['rain_1h'] = self.rain1h
|
||||
data['rain_24h'] = self.rain24h
|
||||
data['rain_since_midnight'] = self.rainSinceMidnight
|
||||
data['temperature'] = self.temperature
|
||||
data['wind_direction'] = self.windDirection
|
||||
data['wind_gust'] = self.windGust
|
||||
data['wind_speed'] = self.windSpeed
|
||||
data['luminosity'] = self.luminosity
|
||||
data['snow'] = self.snow
|
||||
data['wx_raw_timestamp'] = self.wxRawTimestamp
|
||||
return data
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class Sender(Model):
|
||||
"""Sender represents the sender of a packet (often same name as station name)
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
|
||||
self.id = None
|
||||
self.name = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (self.name == ''):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Since packet will be inserted in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (not self.isExistingObject()):
|
||||
insertCursor = self.db.cursor()
|
||||
insertCursor.execute(
|
||||
"""insert into sender(name) values(%s) RETURNING id""", (self.name.strip(
|
||||
),)
|
||||
)
|
||||
self.id = insertCursor.fetchone()[0]
|
||||
insertCursor.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Since packet will be updated in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
import logging
|
||||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class Station(Model):
|
||||
"""Station represents the object/station that the packet is about
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.logger = logging.getLogger('trackdirect')
|
||||
|
||||
self.id = None
|
||||
self.name = None
|
||||
self.latestSenderId = None
|
||||
self.stationTypeId = 1 # default to 1
|
||||
self.sourceId = None
|
||||
|
||||
self.latestPacketId = None
|
||||
self.latestPacketTimestamp = None
|
||||
|
||||
self.latestLocationPacketId = None
|
||||
self.latestLocationPacketTimestamp = None
|
||||
|
||||
self.latestWeatherPacketId = None
|
||||
self.latestWeatherPacketTimestamp = None
|
||||
|
||||
self.latestTelemetryPacketId = None
|
||||
self.latestTelemetryPacketTimestamp = None
|
||||
|
||||
# Latest packet with a location that is confirmed to be correct
|
||||
self.latestConfirmedPacketId = None
|
||||
self.latestConfirmedPacketTimestamp = None
|
||||
self.latestConfirmedSymbol = None
|
||||
self.latestConfirmedSymbolTable = None
|
||||
self.latestConfirmedLatitude = None
|
||||
self.latestConfirmedLongitude = None
|
||||
self.latestConfirmedMarkerId = None
|
||||
|
||||
self.latestOgnPacketId = None
|
||||
self.latestOgnPacketTimestamp = None
|
||||
self.latestOgnSenderAddress = None
|
||||
self.latestOgnAircraftTypeId = None
|
||||
self.latestOgnAddressTypeId = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (self.name == ''):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Since packet will be inserted in batch we never use this method.
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (not self.isExistingObject()):
|
||||
insertCursor = self.db.cursor()
|
||||
insertCursor.execute(
|
||||
"""insert into station(name, station_type_id, source_id) values(%s, %s, %s) RETURNING id""", (
|
||||
self.name.strip(), self.stationTypeId, self.sourceId)
|
||||
)
|
||||
self.id = insertCursor.fetchone()[0]
|
||||
insertCursor.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (self.isExistingObject()):
|
||||
cursor = self.db.cursor()
|
||||
cursor.execute(
|
||||
"""update station set source_id = %s, name = %s, station_type_id = %s where id = %s and source_id is null""", (
|
||||
self.sourceId, self.name, self.stationTypeId, self.id)
|
||||
)
|
||||
cursor.close()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def getShortDict(self):
|
||||
"""Returns a dict representation of the object
|
||||
|
||||
Returns:
|
||||
Dict representation of the object
|
||||
"""
|
||||
data = {}
|
||||
data['id'] = self.id
|
||||
|
||||
data['name'] = self.name
|
||||
data['latest_sender_id'] = self.latestSenderId
|
||||
data['station_type_id'] = self.stationTypeId
|
||||
data['source_id'] = self.sourceId
|
||||
|
||||
if (self.latestConfirmedPacketId is not None):
|
||||
data['latest_confirmed_packet_id'] = int(
|
||||
self.latestConfirmedPacketId)
|
||||
else:
|
||||
data['latest_confirmed_packet_id'] = None
|
||||
|
||||
data['latest_confirmed_packet_timestamp'] = self.latestConfirmedPacketTimestamp
|
||||
data['latest_confirmed_symbol'] = self.latestConfirmedSymbol
|
||||
data['latest_confirmed_symbol_table'] = self.latestConfirmedSymbolTable
|
||||
|
||||
if (self.latestConfirmedLatitude is not None):
|
||||
data['latest_confirmed_latitude'] = float(
|
||||
self.latestConfirmedLatitude)
|
||||
else:
|
||||
data['latest_confirmed_latitude'] = None
|
||||
|
||||
if (self.latestConfirmedLongitude is not None):
|
||||
data['latest_confirmed_longitude'] = float(
|
||||
self.latestConfirmedLongitude)
|
||||
else:
|
||||
data['latest_confirmed_longitude'] = None
|
||||
|
||||
if (self.latestLocationPacketId is not None):
|
||||
data['latest_location_packet_id'] = self.latestLocationPacketId
|
||||
else:
|
||||
data['latest_location_packet_id'] = None
|
||||
|
||||
data['latest_location_packet_timestamp'] = self.latestLocationPacketTimestamp
|
||||
|
||||
if (self.latestPacketId is not None):
|
||||
data['latest_packet_id'] = int(self.latestPacketId)
|
||||
else:
|
||||
data['latest_packet_id'] = None
|
||||
|
||||
data['latest_packet_timestamp'] = self.latestPacketTimestamp
|
||||
|
||||
return data
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class StationTelemetryBits(Model):
|
||||
"""StationTelemetryBits represents the telemetry bits sent by the related station
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.id = None
|
||||
self.stationId = None
|
||||
self.createdTs = None
|
||||
self.latestTs = None
|
||||
self.validToTs = None
|
||||
self.bits = None
|
||||
self.title = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (type(self.stationId) != int or self.stationId <= 0):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def save(self):
|
||||
"""Save object data to database if attribute data is valid
|
||||
|
||||
Returns:
|
||||
Returns true on success otherwise false
|
||||
"""
|
||||
if (self.validate()):
|
||||
if (self.isExistingObject()):
|
||||
return self.update()
|
||||
else:
|
||||
cursor = self.db.cursor()
|
||||
cursor.execute("""update station_telemetry_bits
|
||||
set latest_ts = %s
|
||||
where station_id = %s
|
||||
and valid_to_ts is null
|
||||
and bits = %s
|
||||
and title = %s""",
|
||||
(self.createdTs,
|
||||
self.stationId,
|
||||
self.bits,
|
||||
self.title))
|
||||
|
||||
if (cursor.rowcount == 0):
|
||||
return self.insert()
|
||||
else:
|
||||
# We do not insert it since it was equal to the existsing row
|
||||
return True
|
||||
return False
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (not self.isExistingObject()):
|
||||
insertCursor = self.db.cursor()
|
||||
insertCursor.execute("""update station_telemetry_bits
|
||||
set valid_to_ts = %s
|
||||
where station_id = %s
|
||||
and valid_to_ts is null""",
|
||||
(self.createdTs,
|
||||
self.stationId))
|
||||
|
||||
insertCursor.execute("""insert into station_telemetry_bits(
|
||||
station_id,
|
||||
created_ts,
|
||||
latest_ts,
|
||||
bits,
|
||||
title)
|
||||
values (%s, %s, %s, %s, %s)""",
|
||||
(self.stationId,
|
||||
self.createdTs,
|
||||
self.createdTs,
|
||||
self.bits,
|
||||
self.title))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class StationTelemetryEqns(Model):
|
||||
"""StationTelemetryEqns represents the telemetry equations sent by the related station
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.id = None
|
||||
self.stationId = None
|
||||
self.createdTs = None
|
||||
self.latestTs = None
|
||||
self.validToTs = None
|
||||
self.a1 = None
|
||||
self.b1 = None
|
||||
self.c1 = None
|
||||
self.a2 = None
|
||||
self.b2 = None
|
||||
self.c2 = None
|
||||
self.a3 = None
|
||||
self.b3 = None
|
||||
self.c3 = None
|
||||
self.a4 = None
|
||||
self.b4 = None
|
||||
self.c4 = None
|
||||
self.a5 = None
|
||||
self.b5 = None
|
||||
self.c5 = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (type(self.stationId) != int or self.stationId <= 0):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def save(self):
|
||||
"""Save object data to database if attribute data is valid
|
||||
|
||||
Returns:
|
||||
Returns true on success otherwise false
|
||||
"""
|
||||
if (self.validate()):
|
||||
if (self.isExistingObject()):
|
||||
return self.update()
|
||||
else:
|
||||
cursor = self.db.cursor()
|
||||
cursor.execute("""update station_telemetry_eqns
|
||||
set latest_ts = %s
|
||||
where station_id = %s
|
||||
and valid_to_ts is null
|
||||
and a1::numeric = %s
|
||||
and b1::numeric = %s
|
||||
and c1::numeric = %s
|
||||
|
||||
and a2::numeric = %s
|
||||
and b2::numeric = %s
|
||||
and c2::numeric = %s
|
||||
|
||||
and a3::numeric = %s
|
||||
and b3::numeric = %s
|
||||
and c3::numeric = %s
|
||||
|
||||
and a4::numeric = %s
|
||||
and b4::numeric = %s
|
||||
and c4::numeric = %s
|
||||
|
||||
and a5::numeric = %s
|
||||
and b5::numeric = %s
|
||||
and c5::numeric = %s""",
|
||||
|
||||
(self.createdTs,
|
||||
self.stationId,
|
||||
self.a1,
|
||||
self.b1,
|
||||
self.c1,
|
||||
|
||||
self.a2,
|
||||
self.b2,
|
||||
self.c2,
|
||||
|
||||
self.a3,
|
||||
self.b3,
|
||||
self.c3,
|
||||
|
||||
self.a4,
|
||||
self.b4,
|
||||
self.c4,
|
||||
|
||||
self.a5,
|
||||
self.b5,
|
||||
self.c5))
|
||||
|
||||
if (cursor.rowcount == 0):
|
||||
return self.insert()
|
||||
else:
|
||||
# We do not insert it since it was equal to the existsing row
|
||||
return True
|
||||
return False
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (not self.isExistingObject()):
|
||||
insertCursor = self.db.cursor()
|
||||
insertCursor.execute("""update station_telemetry_eqns
|
||||
set valid_to_ts = %s
|
||||
where station_id = %s
|
||||
and valid_to_ts is null""", (
|
||||
self.createdTs,
|
||||
self.stationId))
|
||||
|
||||
insertCursor.execute("""insert into station_telemetry_eqns(station_id, created_ts, latest_ts, a1, b1, c1, a2, b2, c2, a3, b3, c3, a4, b4, c4, a5, b5, c5)
|
||||
values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
|
||||
(self.stationId,
|
||||
self.createdTs,
|
||||
self.timestamp,
|
||||
|
||||
self.a1,
|
||||
self.b1,
|
||||
self.c1,
|
||||
|
||||
self.a2,
|
||||
self.b2,
|
||||
self.c2,
|
||||
|
||||
self.a3,
|
||||
self.b3,
|
||||
self.c3,
|
||||
|
||||
self.a4,
|
||||
self.b4,
|
||||
self.c4,
|
||||
|
||||
self.a5,
|
||||
self.b5,
|
||||
self.c5))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class StationTelemetryParam(Model):
|
||||
"""StationTelemetryParam represents the telemetry parameters sent by the related station
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.id = None
|
||||
self.stationId = None
|
||||
self.createdTs = None
|
||||
self.latestTs = None
|
||||
self.validToTs = None
|
||||
self.p1 = None
|
||||
self.p2 = None
|
||||
self.p3 = None
|
||||
self.p4 = None
|
||||
self.p5 = None
|
||||
self.b1 = None
|
||||
self.b2 = None
|
||||
self.b3 = None
|
||||
self.b4 = None
|
||||
self.b5 = None
|
||||
self.b6 = None
|
||||
self.b7 = None
|
||||
self.b8 = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (type(self.stationId) != int or self.stationId <= 0):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def save(self):
|
||||
"""Save object data to database if attribute data is valid
|
||||
|
||||
Returns:
|
||||
Returns true on success otherwise false
|
||||
"""
|
||||
if (self.validate()):
|
||||
if (self.isExistingObject()):
|
||||
return self.update()
|
||||
else:
|
||||
cursor = self.db.cursor()
|
||||
cursor.execute("""update station_telemetry_param
|
||||
set latest_ts = %s
|
||||
where station_id = %s
|
||||
and valid_to_ts is null
|
||||
and p1 = %s
|
||||
and p2 = %s
|
||||
and p3 = %s
|
||||
and p4 = %s
|
||||
and p5 = %s
|
||||
and b1 = %s
|
||||
and b2 = %s
|
||||
and b3 = %s
|
||||
and b4 = %s
|
||||
and b5 = %s
|
||||
and b6 = %s
|
||||
and b7 = %s
|
||||
and b8 = %s""",
|
||||
(self.createdTs,
|
||||
self.stationId,
|
||||
self.p1,
|
||||
self.p2,
|
||||
self.p3,
|
||||
self.p4,
|
||||
self.p5,
|
||||
self.b1,
|
||||
self.b2,
|
||||
self.b3,
|
||||
self.b4,
|
||||
self.b5,
|
||||
self.b6,
|
||||
self.b7,
|
||||
self.b8))
|
||||
|
||||
if (cursor.rowcount == 0):
|
||||
return self.insert()
|
||||
else:
|
||||
# We do not insert it since it was equal to the existsing row
|
||||
return True
|
||||
return False
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (not self.isExistingObject()):
|
||||
insertCursor = self.db.cursor()
|
||||
insertCursor.execute("""update station_telemetry_param
|
||||
set valid_to_ts = %s
|
||||
where station_id = %s
|
||||
and valid_to_ts is null""",
|
||||
(self.createdTs,
|
||||
self.stationId))
|
||||
|
||||
insertCursor.execute("""insert into station_telemetry_param(station_id, created_ts, latest_ts, p1, p2, p3, p4, p5, b1, b2, b3, b4, b5, b6, b7, b8)
|
||||
values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
|
||||
(self.stationId,
|
||||
self.createdTs,
|
||||
self.createdTs,
|
||||
self.p1,
|
||||
self.p2,
|
||||
self.p3,
|
||||
self.p4,
|
||||
self.p5,
|
||||
self.b1,
|
||||
self.b2,
|
||||
self.b3,
|
||||
self.b4,
|
||||
self.b5,
|
||||
self.b6,
|
||||
self.b7,
|
||||
self.b8))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
from trackdirect.common.Model import Model
|
||||
|
||||
|
||||
class StationTelemetryUnit(Model):
|
||||
"""StationTelemetryUnit represents the telemetry UNIT sent by the related station
|
||||
"""
|
||||
|
||||
def __init__(self, db):
|
||||
"""The __init__ method.
|
||||
|
||||
Args:
|
||||
db (psycopg2.Connection): Database connection
|
||||
"""
|
||||
Model.__init__(self, db)
|
||||
self.id = None
|
||||
self.stationId = None
|
||||
self.createdTs = None
|
||||
self.latestTs = None
|
||||
self.validToTs = None
|
||||
self.u1 = None
|
||||
self.u2 = None
|
||||
self.u3 = None
|
||||
self.u4 = None
|
||||
self.u5 = None
|
||||
self.l1 = None
|
||||
self.l2 = None
|
||||
self.l3 = None
|
||||
self.l4 = None
|
||||
self.l5 = None
|
||||
self.l6 = None
|
||||
self.l7 = None
|
||||
self.l8 = None
|
||||
|
||||
def validate(self):
|
||||
"""Returns true on success (when object content is valid), otherwise false
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (type(self.stationId) != int or self.stationId <= 0):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def save(self):
|
||||
"""Save object data to database if attribute data is valid
|
||||
|
||||
Returns:
|
||||
Returns true on success otherwise false
|
||||
"""
|
||||
if (self.validate()):
|
||||
if (self.isExistingObject()):
|
||||
return self.update()
|
||||
else:
|
||||
cursor = self.db.cursor()
|
||||
cursor.execute("""update station_telemetry_unit
|
||||
set latest_ts = %s
|
||||
where station_id = %s
|
||||
and valid_to_ts is null
|
||||
and u1 = %s
|
||||
and u2 = %s
|
||||
and u3 = %s
|
||||
and u4 = %s
|
||||
and u5 = %s
|
||||
and l1 = %s
|
||||
and l2 = %s
|
||||
and l3 = %s
|
||||
and l4 = %s
|
||||
and l5 = %s
|
||||
and l6 = %s
|
||||
and l7 = %s
|
||||
and l8 = %s""",
|
||||
(self.createdTs,
|
||||
self.stationId,
|
||||
self.u1,
|
||||
self.u2,
|
||||
self.u3,
|
||||
self.u4,
|
||||
self.u5,
|
||||
self.l1,
|
||||
self.l2,
|
||||
self.l3,
|
||||
self.l4,
|
||||
self.l5,
|
||||
self.l6,
|
||||
self.l7,
|
||||
self.l8))
|
||||
|
||||
if (cursor.rowcount == 0):
|
||||
return self.insert()
|
||||
else:
|
||||
# We do not insert it since it was equal to the existsing row
|
||||
return True
|
||||
return False
|
||||
|
||||
def insert(self):
|
||||
"""Method to call when we want to save a new object to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
if (not self.isExistingObject()):
|
||||
insertCursor = self.db.cursor()
|
||||
insertCursor.execute("""update station_telemetry_unit
|
||||
set valid_to_ts = %s
|
||||
where station_id = %s
|
||||
and valid_to_ts is null""",
|
||||
(self.createdTs,
|
||||
self.stationId))
|
||||
|
||||
insertCursor.execute("""insert into station_telemetry_unit(station_id, created_ts, latest_ts, u1, u2, u3, u4, u5, l1, l2, l3, l4, l5, l6, l7, l8)
|
||||
values (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
|
||||
(self.stationId,
|
||||
self.createdTs,
|
||||
self.createdTs,
|
||||
self.u1,
|
||||
self.u2,
|
||||
self.u3,
|
||||
self.u4,
|
||||
self.u5,
|
||||
self.l1,
|
||||
self.l2,
|
||||
self.l3,
|
||||
self.l4,
|
||||
self.l5,
|
||||
self.l6,
|
||||
self.l7,
|
||||
self.l8))
|
||||
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def update(self):
|
||||
"""Method to call when we want to save changes to database
|
||||
|
||||
Returns:
|
||||
True on success otherwise False
|
||||
"""
|
||||
return False
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
__version__ = "1.0"
|
||||
__author__ = "Per Qvarforth"
|
||||
Loading…
Reference in New Issue