22 Commits

Author SHA1 Message Date
Xavier Olive
b1f8f6ed62 Some annotations for quantities 2023-06-14 22:50:33 +02:00
Junzi Sun
8e2051af68 update test 2023-05-22 17:05:43 +02:00
Paul de Jong
50864b56aa Remove rounding in pyModeS (#147)
* Update bds50.py: round roll to 3 places instead of 1

Provide a bit more detail for smaller roll angles.

* remove rounding

* update poetry

* update poetry

* update test

* update bds06

* update workflow

---------

Co-authored-by: Junzi Sun <junzisun@gmail.com>
2023-05-22 17:00:58 +02:00
dependabot[bot]
8403cb61e4 Bump actions/checkout from 2 to 3 (#145)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-02 14:45:28 +01:00
dependabot[bot]
a5b8d670d3 Bump actions/setup-python from 2 to 4 (#144)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-02 14:45:05 +01:00
Xavier Olive
4e19ecdfa9 minor changes, new release 2023-02-14 18:39:52 +01:00
Nicholas (Nick) Kruzan
0d7a310007 Update py_common.py (#143) 2023-02-12 13:20:42 +01:00
Xavier Olive
66c29840b0 fix build issues 2023-01-19 15:18:16 +01:00
Xavier Olive
99dc2a4f40 limit wheels to windows, otherwise build from src 2022-12-31 00:42:50 +01:00
Xavier Olive
39936e4472 fix publish 2022-12-30 19:53:33 +01:00
Xavier Olive
144ee1710d fix publish 2022-12-30 19:46:15 +01:00
Xavier Olive
09ed997f91 fix publish 2022-12-30 19:40:25 +01:00
Xavier Olive
e437931254 fix publish 2022-12-30 19:36:16 +01:00
Xavier Olive
72fcc794e7 clean dependencies 2022-12-30 19:22:10 +01:00
Xavier Olive
ff12d819da fix publish source 2022-12-30 14:17:36 +01:00
Xavier Olive
dc9d7ea91a fix test runner.os 2022-12-30 14:10:22 +01:00
Xavier Olive
5bc11cd78c fix test runner.os 2022-12-30 14:08:44 +01:00
Xavier Olive
9e6f9c3ffe upload source 2022-12-30 14:05:38 +01:00
dependabot[bot]
e1017bc2e5 Bump codecov/codecov-action from 2 to 3 (#136)
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 2 to 3.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-30 14:02:05 +01:00
Xavier Olive
ebe1f76cd9 dependabot.yml 2022-12-30 13:57:57 +01:00
Xavier Olive
8830ef3dfe fix poetry PATH for windows 2022-12-30 13:50:43 +01:00
Xavier Olive
d999851da5 fix typo and && 2022-12-30 13:42:52 +01:00
20 changed files with 332 additions and 899 deletions

11
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "monthly"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "monthly"

View File

@@ -10,7 +10,6 @@ on:
env: env:
POETRY_VERSION: "1.3.1" POETRY_VERSION: "1.3.1"
PYTHON_VERSION: "3.10"
jobs: jobs:
deploy: deploy:
@@ -18,7 +17,7 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [ubuntu-latest, macos-latest, windows-latest] os: [windows-latest, ubuntu-latest, macos-latest]
python-version: ["3.8", "3.9", "3.10", "3.11"] python-version: ["3.8", "3.9", "3.10", "3.11"]
steps: steps:
@@ -27,7 +26,12 @@ jobs:
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v4 uses: actions/setup-python@v4
with: with:
python-version: ${{ env.PYTHON_VERSION }} python-version: ${{ matrix.python-version }}
- name: Add poetry to windows path
if: "startsWith(runner.os, 'windows')"
run: |
echo "C:\Users\runneradmin\.local\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Install and configure Poetry - name: Install and configure Poetry
uses: snok/install-poetry@v1.3.3 uses: snok/install-poetry@v1.3.3
@@ -55,7 +59,7 @@ jobs:
poetry run twine upload dist/*.whl poetry run twine upload dist/*.whl
- name: Build and publish (source) - name: Build and publish (source)
if: "startsWith(runner.os, 'ubuntu') and env.PYTHON_VERSION == '3.10'" if: ${{ startsWith(runner.os, 'windows') && matrix.python-version == '3.11' }}
env: env:
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}

View File

@@ -20,17 +20,17 @@ jobs:
PYTHON_VERSION: ${{ matrix.python-version }} PYTHON_VERSION: ${{ matrix.python-version }}
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Set up Python - name: Set up Python
uses: actions/setup-python@v2 uses: actions/setup-python@v4
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
# virtualenv cache should depends on OS, Python version and `poetry.lock` (and optionally workflow files). # virtualenv cache should depends on OS, Python version and `poetry.lock` (and optionally workflow files).
- name: Cache Packages - name: Cache Packages
uses: actions/cache@v3 uses: actions/cache@v3
if: runner.os != 'windows-latest' if: ${{ !startsWith(runner.os, 'windows') }}
with: with:
path: | path: |
~/.local ~/.local
@@ -65,7 +65,6 @@ jobs:
poetry run pytest tests --cov --cov-report term-missing poetry run pytest tests --cov --cov-report term-missing
- name: Upload coverage to Codecov - name: Upload coverage to Codecov
if: ${{ github.event_name != 'pull_request_target' }} uses: codecov/codecov-action@v3
uses: codecov/codecov-action@v2
with: with:
env_vars: PYTHON_VERSION env_vars: PYTHON_VERSION

View File

@@ -1,9 +1,10 @@
import os import os
import shutil import shutil
import sys import sys
from distutils.core import Distribution, Extension
from distutils.command import build_ext from distutils.command import build_ext
from distutils.core import Distribution, Extension
# import pip
from Cython.Build import cythonize from Cython.Build import cythonize
@@ -11,16 +12,7 @@ def build() -> None:
compile_args = [] compile_args = []
if sys.platform == "linux": if sys.platform == "linux":
compile_args += [ compile_args += ["-Wno-pointer-sign", "-Wno-unused-variable"]
"-march=native",
"-O3",
"-msse",
"-msse2",
"-mfma",
"-mfpmath=sse",
"-Wno-pointer-sign",
"-Wno-unused-variable",
]
extensions = [ extensions = [
Extension( Extension(

1009
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -82,7 +82,7 @@ def airborne_position(
if lon > 180: if lon > 180:
lon = lon - 360 lon = lon - 360
return round(lat, 5), round(lon, 5) return lat, lon
def airborne_position_with_ref( def airborne_position_with_ref(
@@ -129,7 +129,7 @@ def airborne_position_with_ref(
lon = d_lon * (m + cprlon) lon = d_lon * (m + cprlon)
return round(lat, 5), round(lon, 5) return lat, lon
def altitude(msg: str) -> None | int: def altitude(msg: str) -> None | int:

View File

@@ -19,7 +19,6 @@ def surface_position(
lat_ref: float, lat_ref: float,
lon_ref: float, lon_ref: float,
) -> None | tuple[float, float]: ) -> None | tuple[float, float]:
"""Decode surface position from a pair of even and odd position message, """Decode surface position from a pair of even and odd position message,
the lat/lon of receiver must be provided to yield the correct solution. the lat/lon of receiver must be provided to yield the correct solution.
@@ -92,7 +91,7 @@ def surface_position(
imin = min(range(4), key=dls.__getitem__) imin = min(range(4), key=dls.__getitem__)
lon = lons[imin] lon = lons[imin]
return round(lat, 5), round(lon, 5) return lat, lon
def surface_position_with_ref( def surface_position_with_ref(
@@ -139,12 +138,12 @@ def surface_position_with_ref(
lon = d_lon * (m + cprlon) lon = d_lon * (m + cprlon)
return round(lat, 5), round(lon, 5) return lat, lon
def surface_velocity( def surface_velocity(
msg: str, source: bool = False msg: str, source: bool = False
) -> tuple[None | float, float, int, str]: ) -> tuple[None | float, None | float, int, str]:
"""Decode surface velocity from a surface position message """Decode surface velocity from a surface position message
Args: Args:
@@ -173,7 +172,6 @@ def surface_velocity(
trk_status = int(mb[12]) trk_status = int(mb[12])
if trk_status == 1: if trk_status == 1:
trk = common.bin2int(mb[13:20]) * 360 / 128 trk = common.bin2int(mb[13:20]) * 360 / 128
trk = round(trk, 1)
else: else:
trk = None trk = None

View File

@@ -48,7 +48,6 @@ def airborne_velocity(
spd: None | float spd: None | float
if subtype in (1, 2): if subtype in (1, 2):
v_ew = common.bin2int(mb[14:24]) v_ew = common.bin2int(mb[14:24])
v_ns = common.bin2int(mb[25:35]) v_ns = common.bin2int(mb[25:35])
@@ -77,7 +76,7 @@ def airborne_velocity(
trk = math.degrees(trk) # convert to degrees trk = math.degrees(trk) # convert to degrees
trk = trk if trk >= 0 else trk + 360 # no negative val trk = trk if trk >= 0 else trk + 360 # no negative val
trk_or_hdg = round(trk, 2) trk_or_hdg = trk
spd_type = "GS" spd_type = "GS"
dir_type = "TRUE_NORTH" dir_type = "TRUE_NORTH"
@@ -87,7 +86,6 @@ def airborne_velocity(
hdg = None hdg = None
else: else:
hdg = common.bin2int(mb[14:24]) / 1024 * 360.0 hdg = common.bin2int(mb[14:24]) / 1024 * 360.0
hdg = round(hdg, 2)
trk_or_hdg = hdg trk_or_hdg = hdg

View File

@@ -72,7 +72,7 @@ def wind44(msg: str) -> Tuple[Optional[int], Optional[float]]:
speed = common.bin2int(d[5:14]) # knots speed = common.bin2int(d[5:14]) # knots
direction = common.bin2int(d[14:23]) * 180 / 256 # degree direction = common.bin2int(d[14:23]) * 180 / 256 # degree
return round(speed, 0), round(direction, 1) return speed, direction
def temp44(msg: str) -> Tuple[float, float]: def temp44(msg: str) -> Tuple[float, float]:
@@ -96,10 +96,8 @@ def temp44(msg: str) -> Tuple[float, float]:
value = value - 1024 value = value - 1024
temp = value * 0.25 # celsius temp = value * 0.25 # celsius
temp = round(temp, 2)
temp_alternative = value * 0.125 # celsius temp_alternative = value * 0.125 # celsius
temp_alternative = round(temp_alternative, 3)
return temp, temp_alternative return temp, temp_alternative
@@ -140,7 +138,7 @@ def hum44(msg: str) -> Optional[float]:
hm = common.bin2int(d[50:56]) * 100 / 64 # % hm = common.bin2int(d[50:56]) * 100 / 64 # %
return round(hm, 1) return hm
def turb44(msg: str) -> Optional[int]: def turb44(msg: str) -> Optional[int]:

View File

@@ -171,7 +171,6 @@ def temp45(msg: str) -> Optional[float]:
value = value - 512 value = value - 512
temp = value * 0.25 # celsius temp = value * 0.25 # celsius
temp = round(temp, 1)
return temp return temp

View File

@@ -81,7 +81,7 @@ def roll50(msg: str) -> Optional[float]:
value = value - 512 value = value - 512
angle = value * 45 / 256 # degree angle = value * 45 / 256 # degree
return round(angle, 1) return angle
def trk50(msg: str) -> Optional[float]: def trk50(msg: str) -> Optional[float]:
@@ -110,7 +110,7 @@ def trk50(msg: str) -> Optional[float]:
if trk < 0: if trk < 0:
trk = 360 + trk trk = 360 + trk
return round(trk, 3) return trk
def gs50(msg: str) -> Optional[float]: def gs50(msg: str) -> Optional[float]:
@@ -154,7 +154,7 @@ def rtrk50(msg: str) -> Optional[float]:
value = value - 512 value = value - 512
angle = value * 8 / 256 # degree / sec angle = value * 8 / 256 # degree / sec
return round(angle, 3) return angle
def tas50(msg: str) -> Optional[float]: def tas50(msg: str) -> Optional[float]:

View File

@@ -86,7 +86,7 @@ def hdg53(msg: str) -> Optional[float]:
if hdg < 0: if hdg < 0:
hdg = 360 + hdg hdg = 360 + hdg
return round(hdg, 3) return hdg
def ias53(msg: str) -> Optional[float]: def ias53(msg: str) -> Optional[float]:
@@ -122,7 +122,7 @@ def mach53(msg: str) -> Optional[float]:
return None return None
mach = common.bin2int(d[24:33]) * 0.008 mach = common.bin2int(d[24:33]) * 0.008
return round(mach, 3) return mach
def tas53(msg: str) -> Optional[float]: def tas53(msg: str) -> Optional[float]:
@@ -140,7 +140,7 @@ def tas53(msg: str) -> Optional[float]:
return None return None
tas = common.bin2int(d[34:46]) * 0.5 # kts tas = common.bin2int(d[34:46]) * 0.5 # kts
return round(tas, 1) return tas
def vr53(msg: str) -> Optional[int]: def vr53(msg: str) -> Optional[int]:

View File

@@ -200,7 +200,6 @@ def selected_heading(msg: str) -> None | float:
else: else:
hdg_sign = int(mb[30]) hdg_sign = int(mb[30])
hdg = (hdg_sign + 1) * common.bin2int(mb[31:39]) * (180 / 256) hdg = (hdg_sign + 1) * common.bin2int(mb[31:39]) * (180 / 256)
hdg = round(hdg, 2)
return hdg return hdg

View File

@@ -1,4 +1,5 @@
from typing import TypedDict from typing import TypedDict
from typing_extensions import Annotated
from .decode import flarm as flarm_decode from .decode import flarm as flarm_decode
@@ -10,8 +11,8 @@ class DecodedMessage(TypedDict):
icao24: str icao24: str
latitude: float latitude: float
longitude: float longitude: float
altitude: int altitude: Annotated[int, "m"]
vertical_speed: float vertical_speed: Annotated[float, "m/s"]
groundspeed: int groundspeed: int
track: int track: int
type: str type: str

View File

@@ -130,12 +130,12 @@ def flarm(long timestamp, str msg, float refLat, float refLon, **kwargs):
return dict( return dict(
timestamp=timestamp, timestamp=timestamp,
icao24=icao24, icao24=icao24,
latitude=round(lat * 1e-7, 6), latitude=lat * 1e-7,
longitude=round(lon * 1e-7, 6), longitude=lon * 1e-7,
geoaltitude=altitude, geoaltitude=altitude,
vertical_speed=raw_vs * mult_factor / 10, vertical_speed=raw_vs * mult_factor / 10,
groundspeed=round(speed), groundspeed=speed,
track=round(heading4 - 4 * turningRate(heading4, heading8) / 4), track=heading4 - 4 * turningRate(heading4, heading8) / 4,
type=AIRCRAFT_TYPES[aircraft_type], type=AIRCRAFT_TYPES[aircraft_type],
sensorLatitude=refLat, sensorLatitude=refLat,
sensorLongitude=refLon, sensorLongitude=refLon,

View File

@@ -1,14 +1,22 @@
from __future__ import annotations
import time import time
import traceback import traceback
import numpy as np import numpy as np
import pyModeS as pms import pyModeS as pms
from typing import Any
import_msg = """
---------------------------------------------------------------------
Warning: pyrtlsdr not installed (required for using RTL-SDR devices)!
---------------------------------------------------------------------"""
try: try:
import rtlsdr # type: ignore import rtlsdr # type: ignore
except: except ImportError:
print("------------------------------------------------------------------------") print(import_msg)
print("! Warning: pyrtlsdr not installed (required for using RTL-SDR devices) !")
print("------------------------------------------------------------------------")
sampling_rate = 2e6 sampling_rate = 2e6
smaples_per_microsec = 2 smaples_per_microsec = 2
@@ -24,9 +32,9 @@ th_amp_diff = 0.8 # signal amplitude threshold difference between 0 and 1 bit
class RtlReader(object): class RtlReader(object):
def __init__(self, **kwargs): def __init__(self, **kwargs) -> None:
super(RtlReader, self).__init__() super(RtlReader, self).__init__()
self.signal_buffer = [] # amplitude of the sample only self.signal_buffer: list[float] = [] # amplitude of the sample only
self.sdr = rtlsdr.RtlSdr() self.sdr = rtlsdr.RtlSdr()
self.sdr.sample_rate = sampling_rate self.sdr.sample_rate = sampling_rate
self.sdr.center_freq = modes_frequency self.sdr.center_freq = modes_frequency
@@ -39,7 +47,7 @@ class RtlReader(object):
self.exception_queue = None self.exception_queue = None
def _calc_noise(self): def _calc_noise(self) -> float:
"""Calculate noise floor""" """Calculate noise floor"""
window = smaples_per_microsec * 100 window = smaples_per_microsec * 100
total_len = len(self.signal_buffer) total_len = len(self.signal_buffer)
@@ -50,7 +58,7 @@ class RtlReader(object):
) )
return min(means) return min(means)
def _process_buffer(self): def _process_buffer(self) -> list[list[Any]]:
"""process raw IQ data in the buffer""" """process raw IQ data in the buffer"""
# update noise floor # update noise floor
@@ -70,17 +78,18 @@ class RtlReader(object):
i += 1 i += 1
continue continue
if self._check_preamble(self.signal_buffer[i : i + pbits * 2]): frame_start = i + pbits * 2
frame_start = i + pbits * 2 if self._check_preamble(self.signal_buffer[i:frame_start]):
frame_end = i + pbits * 2 + (fbits + 1) * 2
frame_length = (fbits + 1) * 2 frame_length = (fbits + 1) * 2
frame_end = frame_start + frame_length
frame_pulses = self.signal_buffer[frame_start:frame_end] frame_pulses = self.signal_buffer[frame_start:frame_end]
threshold = max(frame_pulses) * 0.2 threshold = max(frame_pulses) * 0.2
msgbin = [] msgbin: list[int] = []
for j in range(0, frame_length, 2): for j in range(0, frame_length, 2):
p2 = frame_pulses[j : j + 2] j_2 = j + 2
p2 = frame_pulses[j:j_2]
if len(p2) < 2: if len(p2) < 2:
break break
@@ -117,7 +126,7 @@ class RtlReader(object):
return messages return messages
def _check_preamble(self, pulses): def _check_preamble(self, pulses) -> bool:
if len(pulses) != 16: if len(pulses) != 16:
return False return False
@@ -127,7 +136,7 @@ class RtlReader(object):
return True return True
def _check_msg(self, msg): def _check_msg(self, msg) -> bool:
df = pms.df(msg) df = pms.df(msg)
msglen = len(msg) msglen = len(msg)
if df == 17 and msglen == 28: if df == 17 and msglen == 28:
@@ -137,8 +146,9 @@ class RtlReader(object):
return True return True
elif df in [4, 5, 11] and msglen == 14: elif df in [4, 5, 11] and msglen == 14:
return True return True
return False
def _debug_msg(self, msg): def _debug_msg(self, msg) -> None:
df = pms.df(msg) df = pms.df(msg)
msglen = len(msg) msglen = len(msg)
if df == 17 and msglen == 28: if df == 17 and msglen == 28:
@@ -151,7 +161,7 @@ class RtlReader(object):
# print("[*]", msg) # print("[*]", msg)
pass pass
def _read_callback(self, data, rtlsdr_obj): def _read_callback(self, data, rtlsdr_obj) -> None:
amp = np.absolute(data) amp = np.absolute(data)
self.signal_buffer.extend(amp.tolist()) self.signal_buffer.extend(amp.tolist())
@@ -159,16 +169,18 @@ class RtlReader(object):
messages = self._process_buffer() messages = self._process_buffer()
self.handle_messages(messages) self.handle_messages(messages)
def handle_messages(self, messages): def handle_messages(self, messages) -> None:
"""re-implement this method to handle the messages""" """re-implement this method to handle the messages"""
for msg, t in messages: for msg, t in messages:
# print("%15.9f %s" % (t, msg)) # print("%15.9f %s" % (t, msg))
pass pass
def stop(self, *args, **kwargs): def stop(self, *args, **kwargs) -> None:
self.sdr.close() self.sdr.close()
def run(self, raw_pipe_in=None, stop_flag=None, exception_queue=None): def run(
self, raw_pipe_in=None, stop_flag=None, exception_queue=None
) -> None:
self.raw_pipe_in = raw_pipe_in self.raw_pipe_in = raw_pipe_in
self.exception_queue = exception_queue self.exception_queue = exception_queue
self.stop_flag = stop_flag self.stop_flag = stop_flag

View File

@@ -231,7 +231,7 @@ def squawk(binstr: str) -> str:
binstr (String): 13 bits binary string binstr (String): 13 bits binary string
Returns: Returns:
int: altitude in ft string: squawk code
""" """
if len(binstr) != 13 or not set(binstr).issubset(set("01")): if len(binstr) != 13 or not set(binstr).issubset(set("01")):

View File

@@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "pyModeS" name = "pyModeS"
version = "2.12" version = "2.16"
description = "Python Mode-S and ADS-B Decoder" description = "Python Mode-S and ADS-B Decoder"
authors = ["Junzi Sun <j.sun-1@tudelft.nl>"] authors = ["Junzi Sun <j.sun-1@tudelft.nl>"]
license = "GNU GPL v3" license = "GNU GPL v3"
@@ -22,7 +22,7 @@ include = [
"*.pxd", "*.pxd",
"*.pyi", "*.pyi",
"py.typed", "py.typed",
{ path = "src/pyModeS/**/*.so", format = "wheel" } { path = "pyModeS/**/*.so", format = "wheel" }
] ]
[tool.poetry.build] [tool.poetry.build]
@@ -39,7 +39,6 @@ pyzmq = "^24.0"
pyrtlsdr = {version = "^0.2.93", optional = true} pyrtlsdr = {version = "^0.2.93", optional = true}
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
Cython = "^0.29.32"
mypy = "^0.991" mypy = "^0.991"
flake8 = "^5.0.0" flake8 = "^5.0.0"
black = "^22.12.0" black = "^22.12.0"
@@ -47,7 +46,6 @@ isort = "^5.11.4"
pytest = "^7.2.0" pytest = "^7.2.0"
pytest-cov = "^4.0.0" pytest-cov = "^4.0.0"
codecov = "^2.1.12" codecov = "^2.1.12"
ipykernel = "^6.20.0"
[tool.poetry.extras] [tool.poetry.extras]
rtlsdr = ["pyrtlsdr"] rtlsdr = ["pyrtlsdr"]

View File

@@ -1,4 +1,5 @@
from pyModeS import adsb from pyModeS import adsb
from pytest import approx
# === TEST ADS-B package === # === TEST ADS-B package ===
@@ -22,7 +23,7 @@ def test_adsb_position():
1446332400, 1446332400,
1446332405, 1446332405,
) )
assert pos == (49.81755, 6.08442) assert pos == (approx(49.81755, 0.001), approx(6.08442, 0.001))
def test_adsb_position_swap_odd_even(): def test_adsb_position_swap_odd_even():
@@ -32,32 +33,32 @@ def test_adsb_position_swap_odd_even():
1446332405, 1446332405,
1446332400, 1446332400,
) )
assert pos == (49.81755, 6.08442) assert pos == (approx(49.81755, 0.001), approx(6.08442, 0.001))
def test_adsb_position_with_ref(): def test_adsb_position_with_ref():
pos = adsb.position_with_ref("8D40058B58C901375147EFD09357", 49.0, 6.0) pos = adsb.position_with_ref("8D40058B58C901375147EFD09357", 49.0, 6.0)
assert pos == (49.82410, 6.06785) assert pos == (approx(49.82410, 0.001), approx(6.06785, 0.001))
pos = adsb.position_with_ref("8FC8200A3AB8F5F893096B000000", -43.5, 172.5) pos = adsb.position_with_ref("8FC8200A3AB8F5F893096B000000", -43.5, 172.5)
assert pos == (-43.48564, 172.53942) assert pos == (approx(-43.48564, 0.001), approx(172.53942, 0.001))
def test_adsb_airborne_position_with_ref(): def test_adsb_airborne_position_with_ref():
pos = adsb.airborne_position_with_ref( pos = adsb.airborne_position_with_ref(
"8D40058B58C901375147EFD09357", 49.0, 6.0 "8D40058B58C901375147EFD09357", 49.0, 6.0
) )
assert pos == (49.82410, 6.06785) assert pos == (approx(49.82410, 0.001), approx(6.06785, 0.001))
pos = adsb.airborne_position_with_ref( pos = adsb.airborne_position_with_ref(
"8D40058B58C904A87F402D3B8C59", 49.0, 6.0 "8D40058B58C904A87F402D3B8C59", 49.0, 6.0
) )
assert pos == (49.81755, 6.08442) assert pos == (approx(49.81755, 0.001), approx(6.08442, 0.001))
def test_adsb_surface_position_with_ref(): def test_adsb_surface_position_with_ref():
pos = adsb.surface_position_with_ref( pos = adsb.surface_position_with_ref(
"8FC8200A3AB8F5F893096B000000", -43.5, 172.5 "8FC8200A3AB8F5F893096B000000", -43.5, 172.5
) )
assert pos == (-43.48564, 172.53942) assert pos == (approx(-43.48564, 0.001), approx(172.53942, 0.001))
def test_adsb_surface_position(): def test_adsb_surface_position():
@@ -69,7 +70,7 @@ def test_adsb_surface_position():
-43.496, -43.496,
172.558, 172.558,
) )
assert pos == (-43.48564, 172.53942) assert pos == (approx(-43.48564, 0.001), approx(172.53942, 0.001))
def test_adsb_alt(): def test_adsb_alt():
@@ -80,9 +81,9 @@ def test_adsb_velocity():
vgs = adsb.velocity("8D485020994409940838175B284F") vgs = adsb.velocity("8D485020994409940838175B284F")
vas = adsb.velocity("8DA05F219B06B6AF189400CBC33F") vas = adsb.velocity("8DA05F219B06B6AF189400CBC33F")
vgs_surface = adsb.velocity("8FC8200A3AB8F5F893096B000000") vgs_surface = adsb.velocity("8FC8200A3AB8F5F893096B000000")
assert vgs == (159, 182.88, -832, "GS") assert vgs == (159, approx(182.88, 0.1), -832, "GS")
assert vas == (375, 243.98, -2304, "TAS") assert vas == (375, approx(243.98, 0.1), -2304, "TAS")
assert vgs_surface == (19, 42.2, 0, "GS") assert vgs_surface == (19, approx(42.2, 0.1), 0, "GS")
assert adsb.altitude_diff("8D485020994409940838175B284F") == 550 assert adsb.altitude_diff("8D485020994409940838175B284F") == 550
@@ -96,7 +97,9 @@ def test_adsb_target_state_status():
sel_alt = adsb.selected_altitude("8DA05629EA21485CBF3F8CADAEEB") sel_alt = adsb.selected_altitude("8DA05629EA21485CBF3F8CADAEEB")
assert sel_alt == (16992, "MCP/FCU") assert sel_alt == (16992, "MCP/FCU")
assert adsb.baro_pressure_setting("8DA05629EA21485CBF3F8CADAEEB") == 1012.8 assert adsb.baro_pressure_setting("8DA05629EA21485CBF3F8CADAEEB") == 1012.8
assert adsb.selected_heading("8DA05629EA21485CBF3F8CADAEEB") == 66.8 assert adsb.selected_heading("8DA05629EA21485CBF3F8CADAEEB") == approx(
66.8, 0.1
)
assert adsb.autopilot("8DA05629EA21485CBF3F8CADAEEB") is True assert adsb.autopilot("8DA05629EA21485CBF3F8CADAEEB") is True
assert adsb.vnav_mode("8DA05629EA21485CBF3F8CADAEEB") is True assert adsb.vnav_mode("8DA05629EA21485CBF3F8CADAEEB") is True
assert adsb.altitude_hold_mode("8DA05629EA21485CBF3F8CADAEEB") is False assert adsb.altitude_hold_mode("8DA05629EA21485CBF3F8CADAEEB") is False

View File

@@ -1,5 +1,5 @@
from pyModeS import bds, commb from pyModeS import bds, commb
import pytest from pytest import approx
# from pyModeS import ehs, els # deprecated # from pyModeS import ehs, els # deprecated
@@ -23,32 +23,24 @@ def test_bds40_functions():
def test_bds50_functions(): def test_bds50_functions():
assert bds.bds50.roll50("A000139381951536E024D4CCF6B5") == 2.1 msg1 = "A000139381951536E024D4CCF6B5"
assert bds.bds50.roll50("A0001691FFD263377FFCE02B2BF9") == -0.4 msg2 = "A0001691FFD263377FFCE02B2BF9"
assert bds.bds50.trk50("A000139381951536E024D4CCF6B5") == 114.258
assert bds.bds50.gs50("A000139381951536E024D4CCF6B5") == 438
assert bds.bds50.rtrk50("A000139381951536E024D4CCF6B5") == 0.125
assert bds.bds50.tas50("A000139381951536E024D4CCF6B5") == 424
assert commb.roll50("A000139381951536E024D4CCF6B5") == 2.1 for module in [bds.bds50, commb]:
assert commb.roll50("A0001691FFD263377FFCE02B2BF9") == -0.4 # signed value assert module.roll50(msg1) == approx(2.1, 0.01)
assert commb.trk50("A000139381951536E024D4CCF6B5") == 114.258 assert module.roll50(msg2) == approx(-0.35, 0.01) # signed value
assert commb.gs50("A000139381951536E024D4CCF6B5") == 438 assert module.trk50(msg1) == approx(114.258, 0.1)
assert commb.rtrk50("A000139381951536E024D4CCF6B5") == 0.125 assert module.gs50(msg1) == 438
assert commb.tas50("A000139381951536E024D4CCF6B5") == 424 assert module.rtrk50(msg1) == 0.125
assert module.tas50(msg1) == 424
def test_bds60_functions(): def test_bds60_functions():
msg = "A00004128F39F91A7E27C46ADC21" msg = "A00004128F39F91A7E27C46ADC21"
assert bds.bds60.hdg60(msg) == pytest.approx(42.71484) for module in [bds.bds60, commb]:
assert bds.bds60.ias60(msg) == 252 assert bds.bds60.hdg60(msg) == approx(42.71484)
assert bds.bds60.mach60(msg) == 0.42 assert bds.bds60.ias60(msg) == 252
assert bds.bds60.vr60baro(msg) == -1920 assert bds.bds60.mach60(msg) == 0.42
assert bds.bds60.vr60ins(msg) == -1920 assert bds.bds60.vr60baro(msg) == -1920
assert bds.bds60.vr60ins(msg) == -1920
assert commb.hdg60(msg) == pytest.approx(42.71484)
assert commb.ias60(msg) == 252
assert commb.mach60(msg) == 0.42
assert commb.vr60baro(msg) == -1920
assert commb.vr60ins(msg) == -1920