Compare commits
3 Commits
adsb_encod
...
v2.8
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
228306dd5f | ||
|
|
1c6b39322f | ||
|
|
9dde1b63d6 |
5
Makefile
5
Makefile
@@ -8,11 +8,12 @@ ext:
|
||||
python setup.py build_ext --inplace
|
||||
|
||||
test:
|
||||
python setup.py build_ext --inplace
|
||||
python -m pytest tests
|
||||
|
||||
clean:
|
||||
find pyModeS/decoder -type f -name '*.c' -delete
|
||||
find pyModeS/decoder -type f -name '*.so' -delete
|
||||
find pyModeS -type f -name '*.c' -delete
|
||||
find pyModeS -type f -name '*.so' -delete
|
||||
find . | grep -E "(__pycache__|\.pyc|\.pyo$$)" | xargs rm -rf
|
||||
rm -rf *.egg-info
|
||||
rm -rf .pytest_cache
|
||||
|
||||
@@ -5,8 +5,8 @@ try:
|
||||
from . import c_common as common
|
||||
from .c_common import *
|
||||
except:
|
||||
from . import common
|
||||
from .common import *
|
||||
from . import py_common as common
|
||||
from .py_common import *
|
||||
|
||||
from .decoder import tell
|
||||
from .decoder import adsb
|
||||
|
||||
@@ -5,7 +5,8 @@ cdef unsigned char int_to_char(unsigned char i)
|
||||
|
||||
cpdef str hex2bin(str hexstr)
|
||||
cpdef long bin2int(str binstr)
|
||||
cpdef long hex2int(str binstr)
|
||||
cpdef long hex2int(str hexstr)
|
||||
cpdef str bin2hex(str binstr)
|
||||
|
||||
cpdef unsigned char df(str msg)
|
||||
cpdef long crc(str msg, bint encode=*)
|
||||
|
||||
@@ -66,6 +66,11 @@ cpdef long hex2int(str hexstr):
|
||||
cumul = 16*cumul + char_to_int(v_hexstr[i])
|
||||
return cumul
|
||||
|
||||
@cython.boundscheck(False)
|
||||
cpdef str bin2hex(str binstr):
|
||||
return "{0:X}".format(int(binstr, 2))
|
||||
|
||||
|
||||
@cython.boundscheck(False)
|
||||
cpdef unsigned char df(str msg):
|
||||
"""Decode Downlink Format vaule, bits 1 to 5."""
|
||||
|
||||
@@ -19,6 +19,11 @@ def bin2int(binstr):
|
||||
return int(binstr, 2)
|
||||
|
||||
|
||||
def bin2hex(binstr):
|
||||
"""Convert a binary string to hexdecimal string."""
|
||||
return "{0:X}".format(int(binstr, 2))
|
||||
|
||||
|
||||
def df(msg):
|
||||
"""Decode Downlink Format value, bits 1 to 5."""
|
||||
dfbin = hex2bin(msg[:2])
|
||||
79
setup.py
79
setup.py
@@ -8,20 +8,12 @@ Steps for deploying a new version:
|
||||
1. Increase the version number
|
||||
2. remove the old deployment under [dist] and [build] folder
|
||||
3. run: python setup.py sdist
|
||||
run: python setup.py bdist_wheel --universal
|
||||
4. twine upload dist/*
|
||||
"""
|
||||
|
||||
# Always prefer setuptools over distutils
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
# Compile some parts
|
||||
from setuptools.extension import Extension
|
||||
from Cython.Build import cythonize
|
||||
|
||||
extensions = [Extension("pyModeS.c_common", ["pyModeS/c_common.pyx"])]
|
||||
|
||||
|
||||
# To use a consistent encoding
|
||||
from codecs import open
|
||||
from os import path
|
||||
@@ -32,78 +24,37 @@ here = path.abspath(path.dirname(__file__))
|
||||
with open(path.join(here, "README.rst"), encoding="utf-8") as f:
|
||||
long_description = f.read()
|
||||
|
||||
setup(
|
||||
|
||||
details = dict(
|
||||
name="pyModeS",
|
||||
# Versions should comply with PEP440. For a discussion on single-sourcing
|
||||
# the version across setup.py and the project code, see
|
||||
# https://packaging.python.org/en/latest/single_source_version.html
|
||||
version="2.5",
|
||||
version="2.8",
|
||||
description="Python Mode-S and ADS-B Decoder",
|
||||
long_description=long_description,
|
||||
# The project's main homepage.
|
||||
url="https://github.com/junzis/pyModeS",
|
||||
# Author details
|
||||
author="Junzi Sun",
|
||||
author_email="j.sun-1@tudelft.nl",
|
||||
# Choose your license
|
||||
license="GNU GPL v3",
|
||||
# See https://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||
classifiers=[
|
||||
# How mature is this project? Common values are
|
||||
# 3 - Alpha
|
||||
# 4 - Beta
|
||||
# 5 - Production/Stable
|
||||
"Development Status :: 4 - Beta",
|
||||
# Indicate who your project is intended for
|
||||
"Intended Audience :: Developers",
|
||||
"Topic :: Software Development :: Libraries",
|
||||
# Pick your license as you wish (should match "license" above)
|
||||
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
|
||||
# Specify the Python versions you support here. In particular, ensure
|
||||
# that you indicate whether you support Python 2, Python 3 or both.
|
||||
# "Programming Language :: Python :: 2",
|
||||
"Programming Language :: Python :: 3",
|
||||
],
|
||||
ext_modules=cythonize(extensions),
|
||||
# What does your project relate to?
|
||||
keywords="Mode-S ADS-B EHS ELS Comm-B",
|
||||
# You can just specify the packages manually here if your project is
|
||||
# simple. Or you can use find_packages().
|
||||
packages=find_packages(exclude=["contrib", "docs", "tests"]),
|
||||
# Alternatively, if you want to distribute just a my_module.py, uncomment
|
||||
# this:
|
||||
# py_modules=["my_module"],
|
||||
# List run-time dependencies here. These will be installed by pip when
|
||||
# your project is installed. For an analysis of "install_requires" vs pip's
|
||||
# requirements files see:
|
||||
# https://packaging.python.org/en/latest/requirements.html
|
||||
install_requires=["numpy", "pyzmq", "pyrtlsdr"],
|
||||
# List additional groups of dependencies here (e.g. development
|
||||
# dependencies). You can install these using the following syntax,
|
||||
# for example:
|
||||
# $ pip install -e .[dev,test]
|
||||
# extras_require={
|
||||
# 'dev': ['check-manifest'],
|
||||
# 'test': ['coverage'],
|
||||
# },
|
||||
# If there are data files included in your packages that need to be
|
||||
# installed, specify them here. If using Python 2.6 or less, then these
|
||||
# have to be included in MANIFEST.in as well.
|
||||
# package_data={
|
||||
# 'sample': ['package_data.dat'],
|
||||
# },
|
||||
# Although 'package_data' is the preferred approach, in some case you may
|
||||
# need to place data files outside of your packages. See:
|
||||
# http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files # noqa
|
||||
# In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
|
||||
# data_files=[('my_data', ['data/data_file'])],
|
||||
# To provide executable scripts, use entry points in preference to the
|
||||
# "scripts" keyword. Entry points provide cross-platform support and allow
|
||||
# pip to create the appropriate form of executable for the target platform.
|
||||
# entry_points={
|
||||
# 'console_scripts': [
|
||||
# 'sample=sample:main',
|
||||
# ],
|
||||
# },
|
||||
package_data={"pyModeS": ["*.pyx", "*.pxd"]},
|
||||
scripts=["pyModeS/streamer/modeslive"],
|
||||
)
|
||||
|
||||
try:
|
||||
from setuptools.extension import Extension
|
||||
from Cython.Build import cythonize
|
||||
|
||||
extensions = [Extension("pyModeS.c_common", ["pyModeS/c_common.pyx"])]
|
||||
|
||||
setup(**dict(details, ext_modules=cythonize(extensions)))
|
||||
|
||||
except:
|
||||
setup(**details)
|
||||
|
||||
@@ -1,58 +1,62 @@
|
||||
try:
|
||||
from pyModeS.decoder import c_common as common
|
||||
|
||||
def test_conversions():
|
||||
assert common.hex2bin("6E406B") == "011011100100000001101011"
|
||||
|
||||
def test_crc_decode():
|
||||
|
||||
assert common.crc("8D406B902015A678D4D220AA4BDA") == 0
|
||||
assert common.crc("8d8960ed58bf053cf11bc5932b7d") == 0
|
||||
assert common.crc("8d45cab390c39509496ca9a32912") == 0
|
||||
assert common.crc("8d74802958c904e6ef4ba0184d5c") == 0
|
||||
assert common.crc("8d4400cd9b0000b4f87000e71a10") == 0
|
||||
assert common.crc("8d4065de58a1054a7ef0218e226a") == 0
|
||||
|
||||
assert common.crc("c80b2dca34aa21dd821a04cb64d4") == 10719924
|
||||
assert common.crc("a800089d8094e33a6004e4b8a522") == 4805588
|
||||
assert common.crc("a8000614a50b6d32bed000bbe0ed") == 5659991
|
||||
assert common.crc("a0000410bc900010a40000f5f477") == 11727682
|
||||
assert common.crc("8d4ca251204994b1c36e60a5343d") == 16
|
||||
assert common.crc("b0001718c65632b0a82040715b65") == 353333
|
||||
|
||||
def test_crc_encode():
|
||||
parity = common.crc("8D406B902015A678D4D220AA4BDA", encode=True)
|
||||
assert parity == 11160538
|
||||
|
||||
def test_icao():
|
||||
assert common.icao("8D406B902015A678D4D220AA4BDA") == "406B90"
|
||||
assert common.icao("A0001839CA3800315800007448D9") == "400940"
|
||||
assert common.icao("A000139381951536E024D4CCF6B5") == "3C4DD2"
|
||||
assert common.icao("A000029CFFBAA11E2004727281F1") == "4243D0"
|
||||
|
||||
def test_modes_altcode():
|
||||
assert common.altcode("A02014B400000000000000F9D514") == 32300
|
||||
|
||||
def test_modes_idcode():
|
||||
assert common.idcode("A800292DFFBBA9383FFCEB903D01") == "1346"
|
||||
|
||||
def test_graycode_to_altitude():
|
||||
assert common.gray2alt("00000000010") == -1000
|
||||
assert common.gray2alt("00000001010") == -500
|
||||
assert common.gray2alt("00000011011") == -100
|
||||
assert common.gray2alt("00000011010") == 0
|
||||
assert common.gray2alt("00000011110") == 100
|
||||
assert common.gray2alt("00000010011") == 600
|
||||
assert common.gray2alt("00000110010") == 1000
|
||||
assert common.gray2alt("00001001001") == 5800
|
||||
assert common.gray2alt("00011100100") == 10300
|
||||
assert common.gray2alt("01100011010") == 32000
|
||||
assert common.gray2alt("01110000100") == 46300
|
||||
assert common.gray2alt("01010101100") == 50200
|
||||
assert common.gray2alt("11011110100") == 73200
|
||||
assert common.gray2alt("10000000011") == 126600
|
||||
assert common.gray2alt("10000000001") == 126700
|
||||
from pyModeS import c_common
|
||||
|
||||
|
||||
except:
|
||||
pass
|
||||
def test_conversions():
|
||||
assert c_common.hex2bin("6E") == "01101110"
|
||||
assert c_common.bin2hex("01101110") == "6E"
|
||||
assert c_common.bin2hex("1101110") == "6E"
|
||||
|
||||
|
||||
def test_crc_decode():
|
||||
|
||||
assert c_common.crc("8D406B902015A678D4D220AA4BDA") == 0
|
||||
assert c_common.crc("8d8960ed58bf053cf11bc5932b7d") == 0
|
||||
assert c_common.crc("8d45cab390c39509496ca9a32912") == 0
|
||||
assert c_common.crc("8d74802958c904e6ef4ba0184d5c") == 0
|
||||
assert c_common.crc("8d4400cd9b0000b4f87000e71a10") == 0
|
||||
assert c_common.crc("8d4065de58a1054a7ef0218e226a") == 0
|
||||
|
||||
assert c_common.crc("c80b2dca34aa21dd821a04cb64d4") == 10719924
|
||||
assert c_common.crc("a800089d8094e33a6004e4b8a522") == 4805588
|
||||
assert c_common.crc("a8000614a50b6d32bed000bbe0ed") == 5659991
|
||||
assert c_common.crc("a0000410bc900010a40000f5f477") == 11727682
|
||||
assert c_common.crc("8d4ca251204994b1c36e60a5343d") == 16
|
||||
assert c_common.crc("b0001718c65632b0a82040715b65") == 353333
|
||||
|
||||
|
||||
def test_crc_encode():
|
||||
parity = c_common.crc("8D406B902015A678D4D220AA4BDA", encode=True)
|
||||
assert parity == 11160538
|
||||
|
||||
|
||||
def test_icao():
|
||||
assert c_common.icao("8D406B902015A678D4D220AA4BDA") == "406B90"
|
||||
assert c_common.icao("A0001839CA3800315800007448D9") == "400940"
|
||||
assert c_common.icao("A000139381951536E024D4CCF6B5") == "3C4DD2"
|
||||
assert c_common.icao("A000029CFFBAA11E2004727281F1") == "4243D0"
|
||||
|
||||
|
||||
def test_modes_altcode():
|
||||
assert c_common.altcode("A02014B400000000000000F9D514") == 32300
|
||||
|
||||
|
||||
def test_modes_idcode():
|
||||
assert c_common.idcode("A800292DFFBBA9383FFCEB903D01") == "1346"
|
||||
|
||||
|
||||
def test_graycode_to_altitude():
|
||||
assert c_common.gray2alt("00000000010") == -1000
|
||||
assert c_common.gray2alt("00000001010") == -500
|
||||
assert c_common.gray2alt("00000011011") == -100
|
||||
assert c_common.gray2alt("00000011010") == 0
|
||||
assert c_common.gray2alt("00000011110") == 100
|
||||
assert c_common.gray2alt("00000010011") == 600
|
||||
assert c_common.gray2alt("00000110010") == 1000
|
||||
assert c_common.gray2alt("00001001001") == 5800
|
||||
assert c_common.gray2alt("00011100100") == 10300
|
||||
assert c_common.gray2alt("01100011010") == 32000
|
||||
assert c_common.gray2alt("01110000100") == 46300
|
||||
assert c_common.gray2alt("01010101100") == 50200
|
||||
assert c_common.gray2alt("11011110100") == 73200
|
||||
assert c_common.gray2alt("10000000011") == 126600
|
||||
assert c_common.gray2alt("10000000001") == 126700
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
from pyModeS import common
|
||||
|
||||
|
||||
def test_conversions():
|
||||
assert common.hex2bin("6E406B") == "011011100100000001101011"
|
||||
|
||||
|
||||
def test_crc_decode():
|
||||
assert common.crc_legacy("8D406B902015A678D4D220AA4BDA") == 0
|
||||
|
||||
assert common.crc("8D406B902015A678D4D220AA4BDA") == 0
|
||||
assert common.crc("8d8960ed58bf053cf11bc5932b7d") == 0
|
||||
assert common.crc("8d45cab390c39509496ca9a32912") == 0
|
||||
assert common.crc("8d49d3d4e1089d00000000744c3b") == 0
|
||||
assert common.crc("8d74802958c904e6ef4ba0184d5c") == 0
|
||||
assert common.crc("8d4400cd9b0000b4f87000e71a10") == 0
|
||||
assert common.crc("8d4065de58a1054a7ef0218e226a") == 0
|
||||
|
||||
assert common.crc("c80b2dca34aa21dd821a04cb64d4") == 10719924
|
||||
assert common.crc("a800089d8094e33a6004e4b8a522") == 4805588
|
||||
assert common.crc("a8000614a50b6d32bed000bbe0ed") == 5659991
|
||||
assert common.crc("a0000410bc900010a40000f5f477") == 11727682
|
||||
assert common.crc("8d4ca251204994b1c36e60a5343d") == 16
|
||||
assert common.crc("b0001718c65632b0a82040715b65") == 353333
|
||||
|
||||
|
||||
def test_crc_encode():
|
||||
parity = common.crc("8D406B902015A678D4D220AA4BDA", encode=True)
|
||||
assert parity == 11160538
|
||||
|
||||
|
||||
def test_icao():
|
||||
assert common.icao("8D406B902015A678D4D220AA4BDA") == "406B90"
|
||||
assert common.icao("A0001839CA3800315800007448D9") == "400940"
|
||||
assert common.icao("A000139381951536E024D4CCF6B5") == "3C4DD2"
|
||||
assert common.icao("A000029CFFBAA11E2004727281F1") == "4243D0"
|
||||
|
||||
|
||||
def test_modes_altcode():
|
||||
assert common.altcode("A02014B400000000000000F9D514") == 32300
|
||||
|
||||
|
||||
def test_modes_idcode():
|
||||
assert common.idcode("A800292DFFBBA9383FFCEB903D01") == "1346"
|
||||
|
||||
|
||||
def test_graycode_to_altitude():
|
||||
assert common.gray2alt("00000000010") == -1000
|
||||
assert common.gray2alt("00000001010") == -500
|
||||
assert common.gray2alt("00000011011") == -100
|
||||
assert common.gray2alt("00000011010") == 0
|
||||
assert common.gray2alt("00000011110") == 100
|
||||
assert common.gray2alt("00000010011") == 600
|
||||
assert common.gray2alt("00000110010") == 1000
|
||||
assert common.gray2alt("00001001001") == 5800
|
||||
assert common.gray2alt("00011100100") == 10300
|
||||
assert common.gray2alt("01100011010") == 32000
|
||||
assert common.gray2alt("01110000100") == 46300
|
||||
assert common.gray2alt("01010101100") == 50200
|
||||
assert common.gray2alt("11011110100") == 73200
|
||||
assert common.gray2alt("10000000011") == 126600
|
||||
assert common.gray2alt("10000000001") == 126700
|
||||
64
tests/test_py_common.py
Normal file
64
tests/test_py_common.py
Normal file
@@ -0,0 +1,64 @@
|
||||
from pyModeS import py_common
|
||||
|
||||
|
||||
def test_conversions():
|
||||
assert py_common.hex2bin("6E") == "01101110"
|
||||
assert py_common.bin2hex("01101110") == "6E"
|
||||
assert py_common.bin2hex("1101110") == "6E"
|
||||
|
||||
|
||||
def test_crc_decode():
|
||||
assert py_common.crc_legacy("8D406B902015A678D4D220AA4BDA") == 0
|
||||
|
||||
assert py_common.crc("8D406B902015A678D4D220AA4BDA") == 0
|
||||
assert py_common.crc("8d8960ed58bf053cf11bc5932b7d") == 0
|
||||
assert py_common.crc("8d45cab390c39509496ca9a32912") == 0
|
||||
assert py_common.crc("8d49d3d4e1089d00000000744c3b") == 0
|
||||
assert py_common.crc("8d74802958c904e6ef4ba0184d5c") == 0
|
||||
assert py_common.crc("8d4400cd9b0000b4f87000e71a10") == 0
|
||||
assert py_common.crc("8d4065de58a1054a7ef0218e226a") == 0
|
||||
|
||||
assert py_common.crc("c80b2dca34aa21dd821a04cb64d4") == 10719924
|
||||
assert py_common.crc("a800089d8094e33a6004e4b8a522") == 4805588
|
||||
assert py_common.crc("a8000614a50b6d32bed000bbe0ed") == 5659991
|
||||
assert py_common.crc("a0000410bc900010a40000f5f477") == 11727682
|
||||
assert py_common.crc("8d4ca251204994b1c36e60a5343d") == 16
|
||||
assert py_common.crc("b0001718c65632b0a82040715b65") == 353333
|
||||
|
||||
|
||||
def test_crc_encode():
|
||||
parity = py_common.crc("8D406B902015A678D4D220AA4BDA", encode=True)
|
||||
assert parity == 11160538
|
||||
|
||||
|
||||
def test_icao():
|
||||
assert py_common.icao("8D406B902015A678D4D220AA4BDA") == "406B90"
|
||||
assert py_common.icao("A0001839CA3800315800007448D9") == "400940"
|
||||
assert py_common.icao("A000139381951536E024D4CCF6B5") == "3C4DD2"
|
||||
assert py_common.icao("A000029CFFBAA11E2004727281F1") == "4243D0"
|
||||
|
||||
|
||||
def test_modes_altcode():
|
||||
assert py_common.altcode("A02014B400000000000000F9D514") == 32300
|
||||
|
||||
|
||||
def test_modes_idcode():
|
||||
assert py_common.idcode("A800292DFFBBA9383FFCEB903D01") == "1346"
|
||||
|
||||
|
||||
def test_graycode_to_altitude():
|
||||
assert py_common.gray2alt("00000000010") == -1000
|
||||
assert py_common.gray2alt("00000001010") == -500
|
||||
assert py_common.gray2alt("00000011011") == -100
|
||||
assert py_common.gray2alt("00000011010") == 0
|
||||
assert py_common.gray2alt("00000011110") == 100
|
||||
assert py_common.gray2alt("00000010011") == 600
|
||||
assert py_common.gray2alt("00000110010") == 1000
|
||||
assert py_common.gray2alt("00001001001") == 5800
|
||||
assert py_common.gray2alt("00011100100") == 10300
|
||||
assert py_common.gray2alt("01100011010") == 32000
|
||||
assert py_common.gray2alt("01110000100") == 46300
|
||||
assert py_common.gray2alt("01010101100") == 50200
|
||||
assert py_common.gray2alt("11011110100") == 73200
|
||||
assert py_common.gray2alt("10000000011") == 126600
|
||||
assert py_common.gray2alt("10000000001") == 126700
|
||||
Reference in New Issue
Block a user