Exemple #1
0
def wind44(msg, rev=False):
    """reported wind speed and direction

    Args:
        msg (String): 28 bytes hexadecimal message (BDS44) string
        rev (bool): using revised version

    Returns:
        (int, float): speed (kt), direction (degree)
    """
    d = hex2bin(data(msg))

    if not rev:
        status = int(d[4])
        if not status:
            return None

        speed = bin2int(d[5:14])   # knots
        direction = bin2int(d[14:23]) * 180.0 / 256.0  # degree

    else:
        spd_status = int(d[4])
        dir_status = int(d[14])

        if (not spd_status) or (not dir_status):
            return None

        speed = bin2int(d[5:14])   # knots
        direction = bin2int(d[15:23]) * 180.0 / 128.0  # degree

    return round(speed, 0), round(direction, 1)
Exemple #2
0
def nac_p(msg):
    """Calculate NACp, Navigation Accuracy Category - Position

    Args:
        msg (string): 28 bytes hexadecimal message string, TC = 29 or 31

    Returns:
        int or string: 95% horizontal accuracy bounds, Estimated Position Uncertainty
        int or string: 95% vertical accuracy bounds, Vertical Estimated Position Uncertainty
    """
    tc = typecode(msg)

    if tc not in [29, 31]:
        raise RuntimeError("%s: Not a target state and status message, \
                           or operation status message, expecting TC = 29 or 31"
                           % msg)

    msgbin = common.hex2bin(msg)

    nacp_df = pd.read_csv(
        '/home/josmilrom/Libraries/pyModeS/pyModeS/decoder/adsb_ua_parameters/NACp.csv',
        sep=',')

    if tc == 29:
        nac_p = common.bin2int(msgbin[71:75])
        nacp_df_extract = nacp_df[nacp_df.NACp == nac_p]
    elif tc == 31:
        nac_p = common.bin2int(msgbin[76:80])
        nacp_df_extract = nacp_df[nacp_df.NACp == nac_p]

    HFU = nacp_df_extract['HFU'][0]
    VEPU = nacp_df_extract['VEPU'][0]

    return HFU, VEPU
Exemple #3
0
def is10(msg):
    """Check if a message is likely to be BDS code 1,0

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        bool: True or False
    """

    if allzeros(msg):
        return False

    d = hex2bin(data(msg))

    # first 8 bits must be 0x10
    if d[0:8] != '00010000':
        return False

    # bit 10 to 14 are reserved
    if bin2int(d[9:14]) != 0:
        return False

    # overlay capabilty conflict
    if d[14] == '1' and bin2int(d[16:23]) < 5:
        return False
    if d[14] == '0' and bin2int(d[16:23]) > 4:
        return False

    return True
Exemple #4
0
def p44(msg, rev=False):
    """reported average static pressure

    Args:
        msg (String): 28 bytes hexadecimal message (BDS44) string
        rev (bool): using revised version

    Returns:
        int: static pressure in hPa
    """
    d = hex2bin(data(msg))

    if not rev:
        if d[34] == '0':
            return None

        p = bin2int(d[35:46])    # hPa

    else:
        if d[35] == '0':
            return None

        p = bin2int(d[36:47])    # hPa

    return p
Exemple #5
0
def hum44(msg, rev=False):
    """reported humidity

    Args:
        msg (String): 28 bytes hexadecimal message (BDS44) string
        rev (bool): using revised version

    Returns:
        float: percentage of humidity, [0 - 100] %
    """
    d = hex2bin(data(msg))

    if not rev:
        if d[49] == '0':
            return None

        hm = bin2int(d[50:56]) * 100.0 / 64    # %

    else:
        if d[48] == '0':
            return None

        hm = bin2int(d[49:56])    # %

    return round(hm, 1)
Exemple #6
0
def nac_p(msg):
    """Calculate NACp, Navigation Accuracy Category - Position

    Args:
        msg (string): 28 bytes hexadecimal message string, TC = 29 or 31

    Returns:
        int or string: 95% horizontal accuracy bounds, Estimated Position Uncertainty
        int or string: 95% vertical accuracy bounds, Vertical Estimated Position Uncertainty
    """
    tc = typecode(msg)

    if tc not in [29, 31]:
        raise RuntimeError("%s: Not a target state and status message, \
                           or operation status message, expecting TC = 29 or 31"
                           % msg)

    msgbin = common.hex2bin(msg)

    if tc == 29:
        NACp = common.bin2int(msgbin[71:75])
    elif tc == 31:
        NACp = common.bin2int(msgbin[76:80])

    try:
        EPU = uncertainty.NACp[NACp]["EPU"]
        VEPU = uncertainty.NACp[NACp]["VEPU"]
    except KeyError:
        EPU, VEPU = uncertainty.NA, uncertainty.NA

    return EPU, VEPU
Exemple #7
0
def altitude(msg):
    """Decode aircraft altitude

    Args:
        msg (string): 28 bytes hexadecimal message string

    Returns:
        int: altitude in feet
    """

    tc = common.typecode(msg)

    if tc < 9 or tc == 19 or tc > 22:
        raise RuntimeError("%s: Not a airborn position message" % msg)

    mb = common.hex2bin(msg)[32:]

    if tc < 19:
        # barometric altitude
        q = mb[15]
        if q:
            n = common.bin2int(mb[8:15] + mb[16:20])
            alt = n * 25 - 1000
        else:
            alt = None
    else:
        # GNSS altitude, meters -> feet
        alt = common.bin2int(mb[8:20]) * 3.28084

    return alt
Exemple #8
0
def airborne_position(msg0, msg1, t0, t1):
    """Decode airborn position from a pair of even and odd position message

    Args:
        msg0 (string): even message (28 bytes hexadecimal string)
        msg1 (string): odd message (28 bytes hexadecimal string)
        t0 (int): timestamps for the even message
        t1 (int): timestamps for the odd message

    Returns:
        (float, float): (latitude, longitude) of the aircraft
    """

    mb0 = common.hex2bin(msg0)[32:]
    mb1 = common.hex2bin(msg1)[32:]

    # 131072 is 2^17, since CPR lat and lon are 17 bits each.
    cprlat_even = common.bin2int(mb0[22:39]) / 131072.0
    cprlon_even = common.bin2int(mb0[39:56]) / 131072.0
    cprlat_odd = common.bin2int(mb1[22:39]) / 131072.0
    cprlon_odd = common.bin2int(mb1[39:56]) / 131072.0

    air_d_lat_even = 360.0 / 60
    air_d_lat_odd = 360.0 / 59

    # compute latitude index 'j'
    j = common.floor(59 * cprlat_even - 60 * cprlat_odd + 0.5)

    lat_even = float(air_d_lat_even * (j % 60 + cprlat_even))
    lat_odd = float(air_d_lat_odd * (j % 59 + cprlat_odd))

    if lat_even >= 270:
        lat_even = lat_even - 360

    if lat_odd >= 270:
        lat_odd = lat_odd - 360

    # check if both are in the same latidude zone, exit if not
    if common.cprNL(lat_even) != common.cprNL(lat_odd):
        return None

    # compute ni, longitude index m, and longitude
    if (t0 > t1):
        lat = lat_even
        nl = common.cprNL(lat)
        ni = max(common.cprNL(lat) - 0, 1)
        m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
        lon = (360.0 / ni) * (m % ni + cprlon_even)
    else:
        lat = lat_odd
        nl = common.cprNL(lat)
        ni = max(common.cprNL(lat) - 1, 1)
        m = common.floor(cprlon_even * (nl - 1) - cprlon_odd * nl + 0.5)
        lon = (360.0 / ni) * (m % ni + cprlon_odd)

    if lon > 180:
        lon = lon - 360

    return round(lat, 5), round(lon, 5)
Exemple #9
0
def surface_velocity(msg, rtn_sources=False):
    """Decode surface velocity from from a surface position message
    Args:
        msg (string): 28 bytes hexadecimal message string
        rtn_source (boolean): If the function will return
            the sources for direction of travel and vertical
            rate. This will change the return value from a four
            element array to a six element array.

    Returns:
        (int, float, int, string, string, None): speed (kt),
            ground track (degree), None for rate of climb/descend (ft/min),
            and speed type ('GS' for ground speed), direction source
            ('true_north' for ground track / true north as reference),
            None rate of climb/descent source.
    """

    if common.typecode(msg) < 5 or common.typecode(msg) > 8:
        raise RuntimeError("%s: Not a surface message, expecting 5<TC<8" % msg)

    mb = common.hex2bin(msg)[32:]

    # ground track
    trk_status = int(mb[12])
    if trk_status == 1:
        trk = common.bin2int(mb[13:20]) * 360.0 / 128.0
        trk = round(trk, 1)
    else:
        trk = None

    # ground movement / speed
    mov = common.bin2int(mb[5:12])

    if mov == 0 or mov > 124:
        spd = None
    elif mov == 1:
        spd = 0
    elif mov == 124:
        spd = 175
    else:
        movs = [2, 9, 13, 39, 94, 109, 124]
        kts = [0.125, 1, 2, 15, 70, 100, 175]
        i = next(m[0] for m in enumerate(movs) if m[1] > mov)
        step = (kts[i] - kts[i - 1]) * 1.0 / (movs[i] - movs[i - 1])
        spd = kts[i - 1] + (mov - movs[i - 1]) * step
        spd = round(spd, 2)

    if rtn_sources:
        return spd, trk, 0, "GS", "true_north", None
    else:
        return spd, trk, 0, "GS"
Exemple #10
0
def callsign(msg):
    """Aircraft callsign

    Args:
        msg (string): 28 bytes hexadecimal message string

    Returns:
        string: callsign
    """

    if common.typecode(msg) < 1 or common.typecode(msg) > 4:
        raise RuntimeError("%s: Not a identification message" % msg)

    chars = '#ABCDEFGHIJKLMNOPQRSTUVWXYZ#####_###############0123456789######'
    msgbin = common.hex2bin(msg)
    csbin = msgbin[40:96]

    cs = ''
    cs += chars[common.bin2int(csbin[0:6])]
    cs += chars[common.bin2int(csbin[6:12])]
    cs += chars[common.bin2int(csbin[12:18])]
    cs += chars[common.bin2int(csbin[18:24])]
    cs += chars[common.bin2int(csbin[24:30])]
    cs += chars[common.bin2int(csbin[30:36])]
    cs += chars[common.bin2int(csbin[36:42])]
    cs += chars[common.bin2int(csbin[42:48])]

    # clean string, remove spaces and marks, if any.
    # cs = cs.replace('_', '')
    cs = cs.replace('#', '')
    return cs
Exemple #11
0
def nac_v(msg):
    """Calculate NACv, Navigation Accuracy Category - Velocity

    Args:
        msg (string): 28 bytes hexadecimal message string, TC = 19

    Returns:
        int or string: 95% horizontal accuracy bounds for velocity, Horizontal Figure of Merit 
        int or string: 95% vertical accuracy bounds for velocity, Vertical Figure of Merit
    """
    tc = typecode(msg)

    if tc != 19:
        raise RuntimeError(
            "%s: Not an airborne velocity message, expecting TC = 19" % msg)

    nacv_df = pd.read_csv(
        '/home/josmilrom/Libraries/pyModeS/pyModeS/decoder/adsb_ua_parameters/NACv.csv',
        sep=',')

    msgbin = common.hex2bin(msg)
    nac_v = common.bin2int(msgbin[42:45])
    nacv_df_extract = nacv_df[nacv_df.NACv == nac_v]
    HFOMr = nacv_df_extract['HFOMr'][0]
    VFOMr = nacv_df_extract['VFOMr'][0]

    return HFOMr, VFOMr
Exemple #12
0
def nuc_v(msg):
    """Calculate NUCv, Navigation Uncertainty Category - Velocity (ADS-B version 1)

    Args:
        msg (string): 28 bytes hexadecimal message string,

    Returns:
        int or string: 95% Horizontal Velocity Error
        int or string: 95% Vertical Velocity Error
    """
    tc = typecode(msg)

    if tc != 19:
        raise RuntimeError(
            "%s: Not an airborne velocity message, expecting TC = 19" % msg)

    msgbin = common.hex2bin(msg)
    NUCv = common.bin2int(msgbin[42:45])

    try:
        HVE = uncertainty.NUCv[NUCv]["HVE"]
        VVE = uncertainty.NUCv[NUCv]["VVE"]
    except KeyError:
        HVE, VVE = uncertainty.NA, uncertainty.NA

    return HVE, VVE
Exemple #13
0
def hdg60(msg):
    """Megnetic heading of aircraft

    Args:
        msg (String): 28 bytes hexadecimal message (BDS60) string

    Returns:
        float: heading in degrees to megnetic north (from 0 to 360)
    """
    d = hex2bin(data(msg))

    if d[0] == '0':
        return None

    sign = int(d[1])    # 1 -> west
    value = bin2int(d[2:12])

    if sign:
        value = value - 1024

    hdg = value * 90 / 512.0  # degree

    # convert from [-180, 180] to [0, 360]
    if hdg < 0:
        hdg = 360 + hdg

    return round(hdg, 3)
Exemple #14
0
def is30(msg):
    """Check if a message is likely to be BDS code 2,0

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        bool: True or False
    """

    if allzeros(msg):
        return False

    d = hex2bin(data(msg))

    if d[0:8] != '00110000':
        return False

    # threat type 3 not assigned
    if d[28:30] == '11':
        return False

    # reserved for ACAS III, in far future
    if bin2int(d[15:22]) >= 48:
        return False

    return True
Exemple #15
0
def is17(msg):
    """Check if a message is likely to be BDS code 1,7

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        bool: True or False
    """

    if allzeros(msg):
        return False

    d = hex2bin(data(msg))

    if bin2int(d[28:56]) != 0:
        return False

    caps = cap17(msg)

    # basic BDS codes for ADS-B shall be supported
    #   assuming ADS-B out is installed (2017EU/2020US mandate)
    if not set(['BDS05', 'BDS06', 'BDS08', 'BDS09', 'BDS20']).issubset(caps):
        return False

    return True
Exemple #16
0
def temp44(msg):
    """Static air temperature.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        float, float: temperature and alternative temperature in Celsius degree.
            Note: Two values returns due to what seems to be an inconsistancy
            error in ICAO 9871 (2008) Appendix A-67.

    """
    d = hex2bin(data(msg))

    sign = int(d[23])
    value = bin2int(d[24:34])

    if sign:
        value = value - 1024

    temp = value * 0.25  # celsius
    temp = round(temp, 2)

    temp_alternative = value * 0.125  # celsius
    temp_alternative = round(temp_alternative, 3)

    return temp, temp_alternative
Exemple #17
0
def nac_v(msg):
    """Calculate NACv, Navigation Accuracy Category - Velocity

    Args:
        msg (string): 28 bytes hexadecimal message string, TC = 19

    Returns:
        int or string: 95% horizontal accuracy bounds for velocity, Horizontal Figure of Merit
        int or string: 95% vertical accuracy bounds for velocity, Vertical Figure of Merit
    """
    tc = typecode(msg)

    if tc != 19:
        raise RuntimeError(
            "%s: Not an airborne velocity message, expecting TC = 19" % msg)

    msgbin = common.hex2bin(msg)
    NACv = common.bin2int(msgbin[42:45])

    try:
        HFOMr = uncertainty.NACv[NACv]["HFOMr"]
        VFOMr = uncertainty.NACv[NACv]["VFOMr"]
    except KeyError:
        HFOMr, VFOMr = uncertainty.NA, uncertainty.NA

    return HFOMr, VFOMr
Exemple #18
0
def altitude(msg):
    """Decode aircraft altitude

    Args:
        msg (string): 28 bytes hexadecimal message string

    Returns:
        int: altitude in feet
    """

    tc = typecode(msg)

    if tc < 5 or tc == 19 or tc > 22:
        raise RuntimeError("%s: Not a position message" % msg)

    if tc >= 5 and tc <= 8:
        # surface position, altitude 0
        return 0

    msgbin = common.hex2bin(msg)
    q = msgbin[47]
    if q:
        n = common.bin2int(msgbin[40:47] + msgbin[48:52])
        alt = n * 25 - 1000
        return alt
    else:
        return None
Exemple #19
0
def trk50(msg):
    """True track angle, BDS 5,0 message

    Args:
        msg (String): 28 bytes hexadecimal message (BDS50) string

    Returns:
        float: angle in degrees to true north (from 0 to 360)
    """
    d = hex2bin(data(msg))

    if d[11] == '0':
        return None

    sign = int(d[12])  # 1 -> west
    value = bin2int(d[13:23])

    if sign:
        value = value - 1024

    trk = value * 90.0 / 512.0

    # convert from [-180, 180] to [0, 360]
    if trk < 0:
        trk = 360 + trk

    return round(trk, 3)
Exemple #20
0
def hdg53(msg):
    """Magnetic heading, BDS 5,3 message

    Args:
        msg (String): 28 bytes hexadecimal message (BDS53) string

    Returns:
        float: angle in degrees to true north (from 0 to 360)
    """
    d = hex2bin(data(msg))

    if d[0] == '0':
        return None

    sign = int(d[1])  # 1 -> west
    value = bin2int(d[2:12])

    if sign:
        value = value - 1024

    hdg = value * 90.0 / 512.0  # degree

    # convert from [-180, 180] to [0, 360]
    if hdg < 0:
        hdg = 360 + hdg

    return round(hdg, 3)
Exemple #21
0
def sil(msg, version):
    """Calculate SIL, Surveillance Integrity Level

    Args:
        msg (string): 28 bytes hexadecimal message string with TC = 29, 31

    Returns:
        int or string: Probability of exceeding Horizontal Radius of Containment RCu 
        int or string: Probability of exceeding Vertical Integrity Containment Region VPL 
        string: SIL supplement based on "per hour" or "per sample"
    """
    tc = typecode(msg)

    if tc not in [29, 31]:
        raise RuntimeError("%s: Not a target state and status messag, \
                           or operation status message, expecting TC = 29 or 31"
                           % msg)

    sil_df = pd.read_csv(
        '/home/josmilrom/Libraries/pyModeS/pyModeS/decoder/adsb_ua_parameters/SIL.csv',
        sep=',')

    msgbin = common.hex2bin(msg)

    if tc == 29:
        sil = common.bin2int(msgbin[76:78])
    elif tc == 31:
        sil = common.bin2int(msg[82:84])

    sil_df_extract = sil_df[sil_df.NACv == sil]
    PR_RCu = sil_df_extract['PR_RCu'][0]
    PE_VPL = sil_df_extract['PE_VPL'][0]

    if version == 1:
        return PR_RCu, PE_VPL
    if version == 2:
        if tc == 29:
            sil_sup = common.bin2int(msgbin[39])
        elif tc == 31:
            sil_sup = common.bin2int(msgbin[86])

        if sil_sup == 0:
            base = "per hour"
        elif sil_sup == 1:
            base = "per sample"

        return PR_RCu, PE_VPL, base
Exemple #22
0
def sil(msg, version):
    """Calculate SIL, Surveillance Integrity Level

    Args:
        msg (string): 28 bytes hexadecimal message string with TC = 29, 31

    Returns:
        int or string: Probability of exceeding Horizontal Radius of Containment RCu
        int or string: Probability of exceeding Vertical Integrity Containment Region VPL
        string: SIL supplement based on per "hour" or "sample", or 'unknown'
    """
    tc = typecode(msg)

    if tc not in [29, 31]:
        raise RuntimeError("%s: Not a target state and status messag, \
                           or operation status message, expecting TC = 29 or 31"
                           % msg)

    msgbin = common.hex2bin(msg)

    if tc == 29:
        SIL = common.bin2int(msgbin[76:78])
    elif tc == 31:
        SIL = common.bin2int(msgbin[82:84])

    try:
        PE_RCu = uncertainty.SIL[SIL]["PE_RCu"]
        PE_VPL = uncertainty.SIL[SIL]["PE_VPL"]
    except KeyError:
        PE_RCu, PE_VPL = uncertainty.NA, uncertainty.NA

    base = "unknown"

    if version == 2:
        if tc == 29:
            SIL_SUP = common.bin2int(msgbin[39])
        elif tc == 31:
            SIL_SUP = common.bin2int(msgbin[86])

        if SIL_SUP == 0:
            base = "hour"
        elif SIL_SUP == 1:
            base = "sample"

    return PE_RCu, PE_VPL, base
Exemple #23
0
def surface_position_with_ref(msg, lat_ref, lon_ref):
    """Decode surface position with only one message,
    knowing reference nearby location, such as previously calculated location,
    ground station, or airport location, etc. The reference position shall
    be with in 45NM of the true position.

    Args:
        msg (string): even message (28 bytes hexadecimal string)
        lat_ref: previous known latitude
        lon_ref: previous known longitude

    Returns:
        (float, float): (latitude, longitude) of the aircraft
    """

    mb = common.hex2bin(msg)[32:]

    cprlat = common.bin2int(mb[22:39]) / 131072.0
    cprlon = common.bin2int(mb[39:56]) / 131072.0

    i = int(mb[21])
    d_lat = 90.0 / 59 if i else 90.0 / 60

    j = common.floor(lat_ref / d_lat) + common.floor(
        0.5 + ((lat_ref % d_lat) / d_lat) - cprlat
    )

    lat = d_lat * (j + cprlat)

    ni = common.cprNL(lat) - i

    if ni > 0:
        d_lon = 90.0 / ni
    else:
        d_lon = 90.0

    m = common.floor(lon_ref / d_lon) + common.floor(
        0.5 + ((lon_ref % d_lon) / d_lon) - cprlon
    )

    lon = d_lon * (m + cprlon)

    return round(lat, 5), round(lon, 5)
Exemple #24
0
def surface_velocity(msg):
    """Decode surface velocity from from a surface position message
    Args:
        msg (string): 28 bytes hexadecimal message string

    Returns:
        (int, float, int, string): speed (kt), ground track (degree),
            rate of climb/descend (ft/min), and speed type
            ('GS' for ground speed, 'AS' for airspeed)
    """

    if common.typecode(msg) < 5 or common.typecode(msg) > 8:
        raise RuntimeError("%s: Not a surface message, expecting 5<TC<8" % msg)

    mb = common.hex2bin(msg)[32:]

    # ground track
    trk_status = int(mb[12])
    if trk_status == 1:
        trk = common.bin2int(mb[13:20]) * 360.0 / 128.0
        trk = round(trk, 1)
    else:
        trk = None

    # ground movment / speed
    mov = common.bin2int(mb[5:12])

    if mov == 0 or mov > 124:
        spd = None
    elif mov == 1:
        spd = 0
    elif mov == 124:
        spd = 175
    else:
        movs = [2, 9, 13, 39, 94, 109, 124]
        kts = [0.125, 1, 2, 15, 70, 100, 175]
        i = next(m[0] for m in enumerate(movs) if m[1] > mov)
        step = (kts[i] - kts[i - 1]) * 1.0 / (movs[i] - movs[i - 1])
        spd = kts[i - 1] + (mov - movs[i - 1]) * step
        spd = round(spd, 2)

    return spd, trk, 0, 'GS'
Exemple #25
0
def wind44(msg):
    """Wind speed and direction.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        (int, float): speed (kt), direction (degree)

    """
    d = hex2bin(data(msg))

    status = int(d[4])
    if not status:
        return None, None

    speed = bin2int(d[5:14])  # knots
    direction = bin2int(d[14:23]) * 180.0 / 256.0  # degree

    return round(speed, 0), round(direction, 1)
Exemple #26
0
def is40(msg):
    """Check if a message is likely to be BDS code 4,0

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        bool: True or False
    """

    if allzeros(msg):
        return False

    d = hex2bin(data(msg))

    # status bit 1, 14, and 27

    if wrongstatus(d, 1, 2, 13):
        return False

    if wrongstatus(d, 14, 15, 26):
        return False

    if wrongstatus(d, 27, 28, 39):
        return False

    if wrongstatus(d, 48, 49, 51):
        return False

    if wrongstatus(d, 54, 55, 56):
        return False

    # bits 40-47 and 52-53 shall all be zero

    if bin2int(d[39:47]) != 0:
        return False

    if bin2int(d[51:53]) != 0:
        return False

    return True
Exemple #27
0
def is45(msg):
    """Check if a message is likely to be BDS code 4,5.

    Meteorological hazard report

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        bool: True or False

    """
    if allzeros(msg):
        return False

    d = hex2bin(data(msg))

    # status bit 1, 4, 7, 10, 13, 16, 27, 39
    if wrongstatus(d, 1, 2, 3):
        return False

    if wrongstatus(d, 4, 5, 6):
        return False

    if wrongstatus(d, 7, 8, 9):
        return False

    if wrongstatus(d, 10, 11, 12):
        return False

    if wrongstatus(d, 13, 14, 15):
        return False

    if wrongstatus(d, 16, 17, 26):
        return False

    if wrongstatus(d, 27, 28, 38):
        return False

    if wrongstatus(d, 39, 40, 51):
        return False

    # reserved
    if bin2int(d[51:56]) != 0:
        return False

    temp = temp45(msg)
    if temp:
        if temp > 60 or temp < -80:
            return False

    return True
Exemple #28
0
def temp44(msg, rev=False):
    """reported air temperature

    Args:
        msg (String): 28 bytes hexadecimal message (BDS44) string
        rev (bool): using revised version

    Returns:
        float: tmeperature in Celsius degree
    """
    d = hex2bin(data(msg))

    if not rev:
        # if d[22] == '0':
        #     return None

        sign = int(d[23])
        value = bin2int(d[24:34])

        if sign:
            value = value - 1024

        temp = value * 0.125   # celsius
        temp = round(temp, 1)
    else:
        # if d[23] == '0':
        #     return None

        sign = int(d[24])
        value = bin2int(d[25:35])

        if sign:
            value = value - 1024

        temp = value * 0.125   # celsius
        temp = round(temp, 1)

    return temp
Exemple #29
0
def p45(msg):
    """Average static pressure.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        int: static pressure in hPa

    """
    d = hex2bin(data(msg))
    if d[26] == "0":
        return None
    p = bin2int(d[27:38])  # hPa
    return p
Exemple #30
0
def rh45(msg):
    """Radio height.

    Args:
        msg (String): 28 bytes hexadecimal message string

    Returns:
        int: radio height in ft

    """
    d = hex2bin(data(msg))
    if d[38] == "0":
        return None
    rh = bin2int(d[39:51]) * 16
    return rh