3 Commits

Author SHA1 Message Date
Junzi Sun
228306dd5f version 2.8 2020-05-04 21:35:29 +02:00
Junzi Sun
1c6b39322f rename common file 2020-05-04 20:34:25 +02:00
Junzi Sun
9dde1b63d6 fix missing bin2hex() 2020-05-04 20:30:33 +02:00
9 changed files with 156 additions and 187 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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=*)

View File

@@ -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."""

View File

@@ -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])

View File

@@ -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)

View File

@@ -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

View File

@@ -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
View 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