From abdafd7deab10117d9fd4d0b25a8633b6bf35b80 Mon Sep 17 00:00:00 2001 From: Junzi Sun Date: Fri, 12 Apr 2019 17:18:03 +0200 Subject: [PATCH] rework BDS 44 and 45 --- pyModeS/decoder/bds/bds44.py | 179 ++++++++++++++--------------------- pyModeS/decoder/bds/bds45.py | 118 +++++++++++++++++++++++ 2 files changed, 191 insertions(+), 106 deletions(-) create mode 100644 pyModeS/decoder/bds/bds45.py diff --git a/pyModeS/decoder/bds/bds44.py b/pyModeS/decoder/bds/bds44.py index c55d7fe..f20d67c 100644 --- a/pyModeS/decoder/bds/bds44.py +++ b/pyModeS/decoder/bds/bds44.py @@ -21,8 +21,10 @@ from __future__ import absolute_import, print_function, division from pyModeS.decoder.common import hex2bin, bin2int, data, allzeros, wrongstatus -def is44(msg, rev=False): - """Check if a message is likely to be BDS code 4,4 + +def is44(msg): + """Check if a message is likely to be BDS code 4,4. + Meteorological routine air report Args: @@ -31,68 +33,47 @@ def is44(msg, rev=False): Returns: bool: True or False - """ + """ if allzeros(msg): return False d = hex2bin(data(msg)) + # status bit 5, 35, 47, 50 + if wrongstatus(d, 5, 6, 23): + return False - if not rev: - # status bit 5, 35, 47, 50 - if wrongstatus(d, 5, 6, 23): - return False + if wrongstatus(d, 35, 36, 46): + return False - if wrongstatus(d, 35, 36, 46): - return False + if wrongstatus(d, 47, 48, 49): + return False - if wrongstatus(d, 47, 48, 49): - return False + if wrongstatus(d, 50, 51, 56): + return False - if wrongstatus(d, 50, 51, 56): - return False + # Bits 1-4 indicate source, values > 4 reserved and should not occur + if bin2int(d[0:4]) > 4: + return False - # Bits 1-4 indicate source, values > 4 reserved and should not occur - if bin2int(d[0:4]) > 4: - return False - else: - # status bit 5, 15, 24, 36, 49 - if wrongstatus(d, 5, 6, 14): - return False - - if wrongstatus(d, 15, 16, 23): - return False - - if wrongstatus(d, 24, 25, 35): - return False - - if wrongstatus(d, 36, 37, 47): - return False - - if wrongstatus(d, 49, 50, 56): - return False - - # Bits 1-4 are reserved and should be zero - if bin2int(d[0:4]) != 0: - return False - - vw = wind44(msg, rev=rev) + vw = wind44(msg) if vw is not None and vw[0] > 250: return False - if temp44(msg): - if temp44(msg) > 60 or temp44(msg) < -80: + temp = temp44(msg) + if temp: + if temp > 60 or temp < -80: return False - elif temp44(msg) == 0: + elif temp == 0: return False return True -def wind44(msg, rev=False): - """reported wind speed and direction +def wind44(msg): + """Wind speed and direction. Args: msg (String): 28 bytes hexadecimal message (BDS44) string @@ -100,32 +81,22 @@ def wind44(msg, rev=False): Returns: (int, float): speed (kt), direction (degree) + """ d = hex2bin(data(msg)) - if not rev: - status = int(d[4]) - if not status: - return None + 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 + speed = bin2int(d[5:14]) # knots + direction = bin2int(d[14:23]) * 180.0 / 256.0 # degree return round(speed, 0), round(direction, 1) -def temp44(msg, rev=False): - """reported air temperature +def temp44(msg): + """Static air temperature. Args: msg (String): 28 bytes hexadecimal message (BDS44) string @@ -133,39 +104,27 @@ def temp44(msg, rev=False): Returns: float: tmeperature in Celsius degree + """ d = hex2bin(data(msg)) - if not rev: - # if d[22] == '0': - # return None + # if d[22] == '0': + # return None - sign = int(d[23]) - value = bin2int(d[24:34]) + sign = int(d[23]) + value = bin2int(d[24:34]) - if sign: - value = value - 1024 + 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) + temp = value * 0.125 # celsius + temp = round(temp, 1) return temp -def p44(msg, rev=False): - """reported average static pressure +def p44(msg): + """Static pressure. Args: msg (String): 28 bytes hexadecimal message (BDS44) string @@ -173,26 +132,20 @@ def p44(msg, rev=False): Returns: int: static pressure in hPa + """ d = hex2bin(data(msg)) - if not rev: - if d[34] == '0': - return None + 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 + p = bin2int(d[35:46]) # hPa return p -def hum44(msg, rev=False): - """reported humidity +def hum44(msg): + """humidity Args: msg (String): 28 bytes hexadecimal message (BDS44) string @@ -203,16 +156,30 @@ def hum44(msg, rev=False): """ d = hex2bin(data(msg)) - if not rev: - if d[49] == '0': - return None + 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]) # % + hm = bin2int(d[50:56]) * 100.0 / 64 # % return round(hm, 1) + + +def turb44(msg): + """Turblence. + + Args: + msg (String): 28 bytes hexadecimal message (BDS44) string + rev (bool): using revised version + + Returns: + int: turbulence level. 0: NIL, 1: Light, 2: Moderate, 3: Severe + + """ + d = hex2bin(data(msg)) + + if d[46] == '0': + return None + + turb = bin2int(d[47:49]) + + return turb diff --git a/pyModeS/decoder/bds/bds45.py b/pyModeS/decoder/bds/bds45.py new file mode 100644 index 0000000..6c8587f --- /dev/null +++ b/pyModeS/decoder/bds/bds45.py @@ -0,0 +1,118 @@ +# Copyright (C) 2018 Junzi Sun (TU Delft) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------ +# BDS 4,5 +# Meteorological hazard report +# ------------------------------------------ + +from __future__ import absolute_import, print_function, division +from pyModeS.decoder.common import hex2bin, bin2int, data, allzeros, wrongstatus + + +def is45(msg): + """Check if a message is likely to be BDS code 4,5. + + Meteorological harzard report + + Args: + msg (String): 28 bytes hexadecimal message string + rev (bool): using revised version + + 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, 17, 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 + + +def temp45(msg): + """Static 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)) + + sign = int(d[16]) + value = bin2int(d[17:26]) + + if sign: + value = value - 512 + + temp = value * 0.25 # celsius + temp = round(temp, 1) + + return temp + + +def p44(msg, rev=False): + """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)) + p = bin2int(d[27:38]) # hPa + return p