Data error correction, Plane str method, Fix Data input

-Failover toggle in mainconf
-Error correction on data only ADSBX v2
-Move tabulate print to str method
-OpenSky and ADSBX v1 fixed, was never updated when squawk was added or new lastpos datetime
This commit is contained in:
Jack Sweeney 2021-07-30 18:27:51 -04:00
parent b76a7fe2ec
commit 2d6a64c764
3 changed files with 36 additions and 31 deletions

View File

@ -181,7 +181,7 @@ try:
obj.run_empty() obj.run_empty()
elif failed: elif failed:
failed_count += 1 failed_count += 1
if failed_count >= 10: if failed_count >= 10 and main_config.getboolean('DATA', 'FAILOVER'):
if source == "OPENS": if source == "OPENS":
source = "ADSBX" source = "ADSBX"
elif source == "ADSBX": elif source == "ADSBX":

View File

@ -6,6 +6,8 @@
SOURCE = OPENS SOURCE = OPENS
#Default amount of time after data loss to trigger a landing when under 10k ft #Default amount of time after data loss to trigger a landing when under 10k ft
DATA_LOSS_MINS = 5 DATA_LOSS_MINS = 5
#Failover from one source to the other, only enable if you have both sources setup.
FAILOVER = FALSE
#Timezone if you want your own time to show in the console, if invalid will be set to UTC. #Timezone if you want your own time to show in the console, if invalid will be set to UTC.
#List of TZs names https://en.wikipedia.org/wiki/List_of_tz_database_time_zones #List of TZs names https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
TZ = UTC TZ = UTC

View File

@ -57,11 +57,12 @@ class Plane:
self.printheader("head") self.printheader("head")
#print (Fore.YELLOW + "OpenSky Sourced Data: ", ac_dict) #print (Fore.YELLOW + "OpenSky Sourced Data: ", ac_dict)
try: try:
self.__dict__.update({'icao' : ac_dict.icao24.upper(), 'callsign' : ac_dict.callsign, 'latitude' : ac_dict.latitude, 'longitude' : ac_dict.longitude, 'on_ground' : bool(ac_dict.on_ground), 'last_contact' : ac_dict.last_contact}) self.__dict__.update({'icao' : ac_dict.icao24.upper(), 'callsign' : ac_dict.callsign, 'latitude' : ac_dict.latitude, 'longitude' : ac_dict.longitude, 'on_ground' : bool(ac_dict.on_ground), 'squawk' : ac_dict.squawk})
if ac_dict.baro_altitude != None: if ac_dict.baro_altitude != None:
self.alt_ft = round(float(ac_dict.baro_altitude) * 3.281) self.alt_ft = round(float(ac_dict.baro_altitude) * 3.281)
elif self.on_ground: elif self.on_ground:
self.alt_ft = 0 self.alt_ft = 0
self.last_pos_datetime = datetime.fromtimestamp(ac_dict.time_position)
except ValueError as e: except ValueError as e:
print("Got data but some data is invalid!") print("Got data but some data is invalid!")
print(e) print(e)
@ -76,9 +77,10 @@ class Plane:
#print (Fore.YELLOW +"ADSBX Sourced Data: ", ac_dict, Style.RESET_ALL) #print (Fore.YELLOW +"ADSBX Sourced Data: ", ac_dict, Style.RESET_ALL)
try: try:
#postime is divided by 1000 to get seconds from milliseconds, from timestamp expects secs. #postime is divided by 1000 to get seconds from milliseconds, from timestamp expects secs.
self.__dict__.update({'icao' : ac_dict['icao'].upper(), 'callsign' : ac_dict['call'], 'reg' : ac_dict['reg'], 'latitude' : float(ac_dict['lat']), 'longitude' : float(ac_dict['lon']), 'alt_ft' : int(ac_dict['alt']), 'on_ground' : bool(int(ac_dict["gnd"])), 'last_contact' : round(float(ac_dict["postime"])/1000)}) self.__dict__.update({'icao' : ac_dict['icao'].upper(), 'callsign' : ac_dict['call'], 'reg' : ac_dict['reg'], 'latitude' : float(ac_dict['lat']), 'longitude' : float(ac_dict['lon']), 'alt_ft' : int(ac_dict['alt']), 'on_ground' : bool(int(ac_dict["gnd"])), 'squawk' : ac_dict['sqk']})
if self.on_ground: if self.on_ground:
self.alt_ft = 0 self.alt_ft = 0
self.last_pos_datetime = datetime.fromtimestamp(int(ac_dict['postime'])/1000)
except ValueError as e: except ValueError as e:
print("Got data but some data is invalid!") print("Got data but some data is invalid!")
@ -133,9 +135,32 @@ class Plane:
print(e) print(e)
print (Fore.YELLOW +"ADSBX Sourced Data: ", ac_dict, Style.RESET_ALL) print (Fore.YELLOW +"ADSBX Sourced Data: ", ac_dict, Style.RESET_ALL)
self.printheader("foot") self.printheader("foot")
else:
#Error Handling for bad data, sometimes it would seem to be ADSB Decode error
if (not self.on_ground) and self.alt_ft <= 25 and self.speed <= 10:
print("Not running check, appears to be bad ADSB Decode")
else: else:
self.feeding = True self.feeding = True
self.run_check() self.run_check()
def __str__(self):
from colorama import Fore, Back, Style
from tabulate import tabulate
if self.last_pos_datetime is not None:
time_since_contact = self.get_time_since(self.last_pos_datetime)
output = [
[(Fore.CYAN + "ICAO" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + self.icao + Style.RESET_ALL)],
[(Fore.CYAN + "Callsign" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + self.callsign + Style.RESET_ALL)] if self.callsign is not None else None,
[(Fore.CYAN + "Reg" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + self.reg + Style.RESET_ALL)] if self.reg is not None else None,
[(Fore.CYAN + "Squawk" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + self.squawk + Style.RESET_ALL)] if self.squawk is not None else None,
[(Fore.CYAN + "Coordinates" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str(self.latitude) + ", " + str(self.longitude) + Style.RESET_ALL)] if self.latitude is not None and self.longitude is not None else None,
[(Fore.CYAN + "Last Contact" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str(time_since_contact).split(".")[0]+ Style.RESET_ALL)] if self.last_pos_datetime is not None else None,
[(Fore.CYAN + "On Ground" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str(self.on_ground) + Style.RESET_ALL)] if self.on_ground is not None else None,
[(Fore.CYAN + "Baro Altitude" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str("{:,} ft".format(self.alt_ft)) + Style.RESET_ALL)] if self.alt_ft is not None else None,
[(Fore.CYAN + "Nav Modes" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + ', '.join(self.nav_modes) + Style.RESET_ALL)] if "nav_modes" in self.__dict__ and self.nav_modes != None else None,
[(Fore.CYAN + "Sel Alt Ft" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str("{:,} ft".format(self.sel_nav_alt)) + Style.RESET_ALL)] if "sel_nav_alt" in self.__dict__ and self.sel_nav_alt is not None else None
]
output = list(filter(None, output))
return tabulate(output, [], 'fancy_grid')
def printheader(self, type): def printheader(self, type):
from colorama import Fore, Back, Style from colorama import Fore, Back, Style
if type == "head": if type == "head":
@ -184,6 +209,7 @@ class Plane:
self.run_check() self.run_check()
def run_check(self): def run_check(self):
"""Runs a check of a plane module to see if its landed or takenoff using plane data, and takes action if so.""" """Runs a check of a plane module to see if its landed or takenoff using plane data, and takes action if so."""
print(self)
#Ability to Remove old Map #Ability to Remove old Map
import os import os
from colorama import Fore, Style from colorama import Fore, Style
@ -196,33 +222,8 @@ class Plane:
ENABLE_ROUTE_LOOKUP = False ENABLE_ROUTE_LOOKUP = False
if self.config.getboolean('DISCORD', 'ENABLE'): if self.config.getboolean('DISCORD', 'ENABLE'):
from defDiscord import sendDis from defDiscord import sendDis
if self.feeding == False: if self.last_pos_datetime is not None:
time_since_contact = self.get_time_since(self.last_pos_datetime) time_since_contact = self.get_time_since(self.last_pos_datetime)
output = [
[(Fore.CYAN + "ICAO" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + self.icao + Style.RESET_ALL)],
[(Fore.CYAN + "Last Contact" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str(time_since_contact) + Style.RESET_ALL)] if time_since_contact != None else None
]
output = list(filter(None, output))
print(tabulate(output, [], 'fancy_grid'))
print("No Data")
elif self.feeding == True:
time_since_contact = self.get_time_since(self.last_pos_datetime)
output = [
[(Fore.CYAN + "ICAO" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + self.icao + Style.RESET_ALL)],
[(Fore.CYAN + "Callsign" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + self.callsign + Style.RESET_ALL)] if self.callsign != None else None,
[(Fore.CYAN + "Reg" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + self.reg + Style.RESET_ALL)] if self.reg != None else None,
#Squawks are latest to oldest
[(Fore.CYAN + "Squawk" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + (self.squawk if self.squawk is not None else "NA") + Style.RESET_ALL)],
[(Fore.CYAN + "Coordinates" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str(self.latitude) + ", " + str(self.longitude) + Style.RESET_ALL)],
[(Fore.CYAN + "Last Contact" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str(time_since_contact).split(".")[0]+ Style.RESET_ALL)],
[(Fore.CYAN + "On Ground" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str(self.on_ground) + Style.RESET_ALL)],
[(Fore.CYAN + "Baro Altitude" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str("{:,} ft".format(self.alt_ft)) + Style.RESET_ALL)],
[(Fore.CYAN + "Nav Modes" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + ', '.join(self.nav_modes) + Style.RESET_ALL)] if "nav_modes" in self.__dict__ and self.nav_modes != None else None,
[(Fore.CYAN + "Sel Alt Ft" + Style.RESET_ALL), (Fore.LIGHTGREEN_EX + str("{:,} ft".format(self.sel_nav_alt)) + Style.RESET_ALL)] if "sel_nav_alt" in self.__dict__ and self.sel_nav_alt != None else None
]
output = list(filter(None, output))
print(tabulate(output, [], 'fancy_grid'))
#Check if below desire ft #Check if below desire ft
desired_ft = 15000 desired_ft = 15000
if self.alt_ft is None or self.alt_ft > desired_ft: if self.alt_ft is None or self.alt_ft > desired_ft:
@ -273,12 +274,14 @@ class Plane:
alt_above_airport = None alt_above_airport = None
if (alt_above_airport != None and alt_above_airport <= 10000) or self.alt_ft <= 15000: if (alt_above_airport != None and alt_above_airport <= 10000) or self.alt_ft <= 15000:
self.landing_plausible = False self.landing_plausible = False
self.on_ground = None
self.landed = True self.landed = True
trigger_type = "data loss" trigger_type = "data loss"
type_header = "Landed near" type_header = "Landed near"
else: else:
print("Alt greater then 10k AGL") print("Alt greater then 10k AGL")
self.landing_plausible = False self.landing_plausible = False
self.on_ground = None
else: else:
self.landed = False self.landed = False