diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6e63c40..0babe0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,13 +1,13 @@ name: Build CI -on: [pull_request, push] +on: [pull_request, push, workflow_dispatch] jobs: test: runs-on: ubuntu-latest steps: - name: Set up Python - uses: actions/setup-python@v1 + uses: actions/setup-python@v2 with: python-version: 3.9 @@ -18,40 +18,67 @@ jobs: fetch-depth: 0 - name: Install dependencies + # cmake ships with the ubuntu-latest runner run: | sudo apt-get install python3-dev graphviz - python3 -m pip install --upgrade pip pylint + python3 -m pip install --upgrade pip pylint mypy python3 -m pip install -r docs/requirements.txt -r requirements.txt - name: Build package for docs extraction and linting examples - id: wheel run: | - python3 setup.py bdist_wheel - python3 -m pip install $(ls dist/pyrf24-*.whl) + python3 setup.py sdist bdist_wheel + python3 -m pip install dist/pyrf24-*.whl + + - name: check python typing + run: mypy src - name: check python examples PEP8 compliance - run: | - pylint examples/*.py --disable=duplicate-code # duplicate-code error gets flagged because some examples use similar code snippets + run: pylint examples/*.py src/pyrf24/*.py --disable=duplicate-code --output-format=json:pylint.json + + - name: Match pylint problems to diff via github annotations + run: python ./.github/workflows/pylint_matcher.py pylint.json - name: Build docs working-directory: docs run: sphinx-build -E -W -b html . _build/html - name: Save built docs as artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: "pyRF24_docs" path: ${{ github.workspace }}/docs/_build/html - name: upload to github pages + # only publish doc changes from main branch if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs/_build/html + - name: Save distributable wheels as artifacts + uses: actions/upload-artifact@v2 + with: + name: "pyRF24_pkg_dist" + path: ${{ github.workspace }}/dist + + - name: Create sdist for testPyPi + # Doing this again to ensure a fresh build env. + # We don't need to upload a bdist as we can check that locally, but + # sdist is used by the piwheels project to create a bdist for RPi OS + run: | + rm -r dist/ _skbuild + python3 setup.py sdist + - name: Validate distribution run: | python3 -m pip install twine - twine check dist/* + python3 -m twine check dist/* + + - name: upload to test PyPi + if: github.event_name == 'push' && github.repository == 'nRF24/pyRF24' && (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main') + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.test_pypi_token }} + run: python3 -m twine upload -r testpypi dist/* diff --git a/.github/workflows/pylint_matcher.py b/.github/workflows/pylint_matcher.py new file mode 100644 index 0000000..f8bcc7c --- /dev/null +++ b/.github/workflows/pylint_matcher.py @@ -0,0 +1,69 @@ +"""Parse output from clang-tidy's stdout""" +import argparse +import pathlib +import json +from typing import Dict, Union, List +import logging + +log_commander = logging.getLogger("PylintMatcher") +log_commander.setLevel(logging.DEBUG) # be sure that log commands are output +console_handler = logging.StreamHandler() # Create special stdout stream handler +console_handler.setFormatter(logging.Formatter("%(message)s")) # no formatted log cmds +log_commander.addHandler(console_handler) # Use special handler for log_commander +log_commander.propagate = False # prevent duplicate messages in the parent logger obj + + +def annotate_pylint_note(obj: Dict[str, Union[int, str]]) -> str: + """Translate a 1 notification from pylint to github's checks API. + + :param dict obj: The JSON object output by pylint (for 1 notification). + A typical JSON object output from pylint looks like: + + .. code-block:: json + + { + "type": "error", + "module": "basic_test", + "obj": "", + "line": 3, + "column": 19, + "path": "tests/basic_test.py", + "symbol": "syntax-error", + "message": "invalid syntax (, line 3)", + "message-id": "E0001" + } + + :Returns: + A `str` that can be used by github's workflow log commands. + """ + priority = { + "convention": "notice", + "refactor": "notice", + "warning": "warning", + "error": "error", + "fatal": "error", + } + return ( + "::{level} file={path},line={line},title={path}:{line}:{col} {symbol} [{code}]" + "::{msg}".format( + level=priority[obj["type"]], + path=obj["path"], + line=obj["line"], + col=obj["column"], + symbol=obj["symbol"], + code=obj["message-id"], + msg=obj["message"], + ) + ) + + +if __name__ == "__main__": + arg_parser = argparse.ArgumentParser() + arg_parser.add_argument("json_output", type=pathlib.Path) + args = arg_parser.parse_args() + + pylint_result: List[Dict[str, Union[int, str]]] = json.loads( + pathlib.Path(args.json_output).read_text(encoding="utf-8") + ) + for note in pylint_result: + log_commander.info(annotate_pylint_note(note)) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 51164ca..7277e2c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,6 +1,7 @@ name: Release Actions on: + workflow_dispatch: release: types: [published] @@ -8,13 +9,13 @@ jobs: upload-pypi: runs-on: ubuntu-latest steps: - - name: Set up Python 3.7 - uses: actions/setup-python@v1 + - name: Set up Python + uses: actions/setup-python@v2 with: - python-version: 3.7 + python-version: 3.9 - name: Checkout Current Repo - uses: actions/checkout@v1 + uses: actions/checkout@v2 with: submodules: true fetch-depth: 0 @@ -24,9 +25,27 @@ jobs: sudo apt install python3-dev python3 -m pip install --upgrade pip python3 -m pip install -r requirements.txt + python3 -m pip install twine + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + with: + platforms: aarch64 + + - name: Build wheels with cibuildwheels + uses: pypa/cibuildwheel@v2.8.1 + env: + CIBW_ARCHS_LINUX: aarch64 + CIBW_SKIP: cp36* pp* cp311* + + - name: Move cross-compiled wheels to dist folder + run: | + mkdir -p dist + mv ./wheelhouse/*.whl ${{ github.workspace }}/dist/ - name: build binary distributable wheel - run: python setup.py bdist_wheel + # sdist for non-supprted platforms will serve as a stub lib install + run: python setup.py sdist - name: Save distributable wheels as artifacts uses: actions/upload-artifact@v2 @@ -34,10 +53,10 @@ jobs: name: "pyRF24_pkg_dist" path: ${{ github.workspace }}/dist - ###### We need a self-hosted runner to build distributable wheels for armv7l - # - name: Publish to PyPi - # env: - # TWINE_USERNAME: __token__ - # TWINE_PASSWORD: ${{ secrets.pypi_token }} - # run: | - # twine upload dist/* + - name: Publish to PyPi + # only upload distributions to PyPi when triggered by a published release + if: github.event_name == 'release' + env: + TWINE_USERNAME: __token__ + TWINE_PASSWORD: ${{ secrets.pypi_token }} + run: twine upload dist/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 40b714d..47c2855 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,9 +7,10 @@ if(SKBUILD) message(STATUS "This project is being built using scikit-build & pybind11") endif() +include(cmake/using_flags.cmake) + add_subdirectory(pybind11) add_subdirectory(RF24/utility) # configure the RF24_DRIVER -include(cmake/using_flags.cmake) ################################# RF24 ############################# diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..c79ef0a --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,20 @@ +recursive-include RF24* * +recursive-include cmake * +recursive-include src/pyrf24 *.cpp *.typed +recursive-include pybind11 * +recursive-exclude */.github * +recursive-exclude */docs * +recursive-exclude */examples* * +recursive-exclude */images * +recursive-exclude */tests * +recursive-exclude */build * +recursive-exclude */cmake/toolchains *.cmake +recursive-exclude RF24/utility/AT* *.h *.cpp *.c +recursive-exclude RF24/utility/Teensy *.h +recursive-exclude RF24/utility/Template* *.h +recursive-exclude RF24/utility/rp2 *.h *.cpp *.txt +recursive-exclude RF24*/pyRF24* * +recursive-exclude RF24Network/RPi/pyRF24Network * +global-exclude .clang-format .clang-tidy .git* library.json library.properties Doxyfile keywords.txt Makefile* doxygen-custom.css **.yml **.yaml *.pdf .pylintrc +exclude */*.md */README* RF24/utility/includes.h RF24/configure +include pyproject.toml setup.py CMakeLists.txt diff --git a/README.rst b/README.rst index b3af75f..e51a9ed 100644 --- a/README.rst +++ b/README.rst @@ -63,9 +63,20 @@ To build this python package locally, you need to have cloned this library's rep git clone --recurse-submodules https://github.com/nRF24/pyRF24.git cd pyRF24 - python -m pip install . + python -m pip install . -v + +.. hint:: + For consecutive build attempts, it is recommended to delete any previous build artifacts + before attempting to build again. + + .. code-block:: bash + + rm -r _skbuild/ dist/ .. note:: + The ``-v`` is optional. Here, we use it to show that pip isn't frozen during the + build process. + Installing the package can take a long time, and you might think that pip is frozen on the step labeled "Building wheel for pyrf24 (pyproject.toml)". Just wait for about 5 minutes (maybe longer on older/slower variants of Raspberry Pi). @@ -81,7 +92,7 @@ it is appropriate to pass an additional argument to the install command: .. code-block:: bash - python setup.py install -DRF24_DRIVER=RPi + python setup.py bdist_wheel -DRF24_DRIVER=RPi Building a wheel ----------------- @@ -110,7 +121,7 @@ same version of CPython, CPU architecture, and C standard lib. .. code-block:: bash - rm -r _skbuild/ + rm -r _skbuild/ dist/ 3. To install a built wheel, simply pass the wheel's path and file name to ``pip install``: @@ -120,7 +131,12 @@ same version of CPython, CPU architecture, and C standard lib. Where the following would be replaced accordingly: - - ``MAJOR.MINOR.PATCH`` is the current version of the pyrf24 package + - ``MAJOR.MINOR.PATCH`` is the current version of the pyrf24 package. + + - If not building a tagged commit, then the version will describe the commit relative to + the number of commits since the latest tag. For example, ``0.1.1.post1.dev3`` is + the third commit (``dev3``) since the first "post release" (``post1``) after the + tagged version ``0.1.1``. This adhere's to `PEP440 `_. - ``cp3X`` is the version of python used to build the wheel (ie ``cp39`` for CPython 3.9) The second occurrence of ``cp3X`` describes the CPython ABI compatibility. - ``ARCH`` is the architecture type of the CPU. This corresponds to the compiler used. diff --git a/RF24 b/RF24 index f9e5075..89358b2 160000 --- a/RF24 +++ b/RF24 @@ -1 +1 @@ -Subproject commit f9e507544686af23bcfe9578a1558bbb08d382c9 +Subproject commit 89358b2df7de37d64f2bba180d61b6d200c54070 diff --git a/RF24Mesh b/RF24Mesh index aacb9dc..105386b 160000 --- a/RF24Mesh +++ b/RF24Mesh @@ -1 +1 @@ -Subproject commit aacb9dc00cdc2cec871d1c49bc08a502beb4f94b +Subproject commit 105386baa2a13e24e595c1bd4f173b353b6c9f26 diff --git a/RF24Network b/RF24Network index 6dcd5f8..122cb6c 160000 --- a/RF24Network +++ b/RF24Network @@ -1 +1 @@ -Subproject commit 6dcd5f8ec3c9eb38ec738a42c81be1a86cbbb83d +Subproject commit 122cb6c399c577dac87ae196a9f6063e3c95164c diff --git a/cmake/using_flags.cmake b/cmake/using_flags.cmake index 45fe11b..29cca8a 100644 --- a/cmake/using_flags.cmake +++ b/cmake/using_flags.cmake @@ -22,11 +22,18 @@ option(MESH_NOMASTER "exclude compiling code that is strictly for master nodes f option(MESH_DEBUG "enable/disable debugging output for RF24Mesh lib" OFF) option(MESH_DEBUG_MINIMAL "enable/disable minimal debugging output for RF24Mesh lib" OFF) +# Disabling IRQ support should be always done because +# IRQ support can be handled in python with different libs. +option(RF24_NO_INTERRUPT "disable IRQ support (dependent on pigpio)" ON) +# does not affect pigpio driver though ############################################### # function to apply flags to applicable targets function(apply_flags target) # apply RF24 flags to all targets + if(RF24_NO_INTERRUPT) + target_compile_definitions(${target} PUBLIC RF24_NO_INTERRUPT) + endif() if(RF24_DEBUG) message(STATUS "RF24_DEBUG asserted for ${target}") target_compile_definitions(${target} PUBLIC SERIAL_DEBUG) diff --git a/docs/index.rst b/docs/index.rst index 000e6fa..537bf73 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -29,4 +29,3 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` -* :ref:`search` diff --git a/docs/rf24_api.rst b/docs/rf24_api.rst index 9c252ed..ca825a0 100644 --- a/docs/rf24_api.rst +++ b/docs/rf24_api.rst @@ -15,81 +15,114 @@ Enum classes RF24 class ---------- -Basic RF24 API -************** .. autoclass:: pyrf24.rf24.RF24 - :members: begin, listen, available, read, write, open_tx_pipe, open_rx_pipe - :special-members: __init__ - -Advanced RF24 API -***************** - -.. autoattribute:: pyrf24.rf24.RF24.failure_detected -.. automethod:: pyrf24.rf24.RF24.print_details -.. automethod:: pyrf24.rf24.RF24.print_pretty_details -.. automethod:: pyrf24.rf24.RF24.sprintf_pretty_details -.. automethod:: pyrf24.rf24.RF24.available_pipe -.. automethod:: pyrf24.rf24.RF24.is_fifo -.. .. autoattribute:: pyrf24.rf24.RF24.rx_fifo_full -.. .. automethod:: pyrf24.rf24.RF24.power_up -.. .. automethod:: pyrf24.rf24.RF24.power_down -.. autoattribute:: pyrf24.rf24.RF24.power -.. automethod:: pyrf24.rf24.RF24.write_fast -.. automethod:: pyrf24.rf24.RF24.write_blocking -.. automethod:: pyrf24.rf24.RF24.tx_standby -.. automethod:: pyrf24.rf24.RF24.write_ack_payload -.. automethod:: pyrf24.rf24.RF24.what_happened -.. automethod:: pyrf24.rf24.RF24.start_fast_write -.. automethod:: pyrf24.rf24.RF24.start_write -.. automethod:: pyrf24.rf24.RF24.reuse_tx -.. automethod:: pyrf24.rf24.RF24.flush_rx -.. automethod:: pyrf24.rf24.RF24.flush_tx -.. .. automethod:: pyrf24.rf24.RF24.test_rpd -.. autoattribute:: pyrf24.rf24.RF24.rpd -.. automethod:: pyrf24.rf24.RF24.close_rx_pipe -.. autoattribute:: pyrf24.rf24.RF24.is_plus_variant -.. autoattribute:: pyrf24.rf24.RF24.is_valid -.. autoattribute:: pyrf24.rf24.RF24.is_chip_connected - -Configurable RF24 API -********************* - -.. .. automethod:: pyrf24.rf24.RF24.set_address_width -.. autoattribute:: pyrf24.rf24.RF24.address_width - -.. automethod:: pyrf24.rf24.RF24.set_retries -.. automethod:: pyrf24.rf24.RF24.get_arc - -.. autoattribute:: pyrf24.rf24.RF24.channel - -.. autoattribute:: pyrf24.rf24.RF24.payload_size -.. automethod:: pyrf24.rf24.RF24.get_dynamic_payload_size -.. .. automethod:: pyrf24.rf24.RF24.enable_ack_payload -.. .. automethod:: pyrf24.rf24.RF24.disable_ack_payload -.. .. automethod:: pyrf24.rf24.RF24.enable_dynamic_payloads -.. .. automethod:: pyrf24.rf24.RF24.disable_dynamic_payloads -.. autoattribute:: pyrf24.rf24.RF24.dynamic_payloads -.. autoattribute:: pyrf24.rf24.RF24.ack_payloads - -.. automethod:: pyrf24.rf24.RF24.enable_dynamic_ack -.. automethod:: pyrf24.rf24.RF24.set_auto_ack - -.. automethod:: pyrf24.RF24.toggle_all_pipes - -.. automethod:: pyrf24.RF24.set_radiation -.. automethod:: pyrf24.rf24.RF24.set_pa_level -.. .. automethod:: pyrf24.rf24.RF24.get_pa_level -.. autoattribute:: pyrf24.rf24.RF24.pa_level -.. .. automethod:: pyrf24.rf24.RF24.set_data_rate -.. .. automethod:: pyrf24.rf24.RF24.get_data_rate -.. autoattribute:: pyrf24.rf24.RF24.data_rate - -.. .. automethod:: pyrf24.rf24.RF24.set_crc_length -.. .. automethod:: pyrf24.rf24.RF24.get_crc_length -.. autoattribute:: pyrf24.rf24.RF24.crc_length - -.. automethod:: pyrf24.rf24.RF24.mask_irq - -.. automethod:: pyrf24.rf24.RF24.start_const_carrier -.. automethod:: pyrf24.rf24.RF24.stop_const_carrier + + Basic RF24 API + ************** + + .. automethod:: __init__ + + .. automethod:: begin + .. autoattribute:: listen + .. automethod:: available + .. automethod:: read + .. automethod:: write + .. automethod:: open_tx_pipe + .. automethod:: open_rx_pipe + + Advanced RF24 API + ***************** + + .. automethod:: toggle_all_pipes + .. autoattribute:: is_valid + .. autoattribute:: is_chip_connected + .. autoattribute:: is_plus_variant + .. automethod:: what_happened + + Debugging Helpers + ~~~~~~~~~~~~~~~~~ + + .. autoattribute:: failure_detected + .. automethod:: print_details + .. automethod:: print_pretty_details + .. automethod:: sprintf_pretty_details + .. automethod:: get_arc + + Advanced Transmission + ~~~~~~~~~~~~~~~~~~~~~ + + .. automethod:: write_ack_payload + .. automethod:: write_fast + .. automethod:: reuse_tx + .. automethod:: write_blocking + .. automethod:: start_fast_write + .. automethod:: start_write + .. automethod:: tx_standby + + Power Management + ~~~~~~~~~~~~~~~~ + + .. autoattribute:: power + + FIFO Management + ~~~~~~~~~~~~~~~ + + .. autoattribute:: rx_fifo_full + .. automethod:: flush_tx + .. automethod:: flush_rx + .. automethod:: is_fifo + + Ambiguous Signal Detection + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + + .. autoattribute:: rpd + .. automethod:: start_const_carrier + .. automethod:: stop_const_carrier + + .. automethod:: available_pipe + .. automethod:: close_rx_pipe + + Configurable RF24 API + ********************* + + .. autoattribute:: address_width + .. automethod:: set_retries + .. automethod:: mask_irq + + Channel (Frequency) + ~~~~~~~~~~~~~~~~~~~ + + .. autoattribute:: channel + + Dynamic Delays + ~~~~~~~~~~~~~~ + + .. autoattribute:: tx_delay + + Payload Sizes + ~~~~~~~~~~~~~ + + .. autoattribute:: payload_size + .. autoattribute:: dynamic_payloads + .. automethod:: get_dynamic_payload_size + + Auto-Acknowledgement + ~~~~~~~~~~~~~~~~~~~~ + + .. automethod:: set_auto_ack + .. autoattribute:: ack_payloads + .. automethod:: enable_dynamic_ack + + Radiation Options + ~~~~~~~~~~~~~~~~~ + + .. automethod:: set_pa_level + .. autoattribute:: pa_level + .. autoattribute:: data_rate + .. automethod:: set_radiation + + CRC Lengths + ~~~~~~~~~~~ + + .. autoattribute:: crc_length diff --git a/docs/rf24_mesh_api.rst b/docs/rf24_mesh_api.rst index 1b11d33..666ec5c 100644 --- a/docs/rf24_mesh_api.rst +++ b/docs/rf24_mesh_api.rst @@ -3,25 +3,33 @@ RF24Mesh API .. automodule:: pyrf24.rf24_mesh -Basic RF24Mesh API ------------------- +RF24Mesh class +************** .. autoclass:: pyrf24.rf24_mesh.RF24Mesh - :members: begin, update, write, node_id, renew_address - :special-members: __init__ - -Advanced RF24Mesh API ---------------------- - -.. automethod:: pyrf24.rf24_mesh.RF24Mesh.check_connection -.. autoattribute:: pyrf24.rf24_mesh.RF24Mesh.mesh_address -.. automethod:: pyrf24.rf24_mesh.RF24Mesh.release_address -.. automethod:: pyrf24.rf24_mesh.RF24Mesh.get_node_id -.. automethod:: pyrf24.rf24_mesh.RF24Mesh.get_address -.. automethod:: pyrf24.rf24_mesh.RF24Mesh.set_address -.. automethod:: pyrf24.rf24_mesh.RF24Mesh.set_channel -.. automethod:: pyrf24.rf24_mesh.RF24Mesh.set_child -.. autoattribute:: pyrf24.rf24_mesh.RF24Mesh.addr_list + + Basic RF24Mesh API + ------------------ + + .. automethod:: __init__ + .. automethod:: begin + .. automethod:: update + .. automethod:: write + .. autoattribute:: node_id + .. automethod:: renew_address + + Advanced RF24Mesh API + --------------------- + + .. automethod:: check_connection + .. autoattribute:: mesh_address + .. automethod:: release_address + .. automethod:: get_node_id + .. automethod:: get_address + .. automethod:: set_address + .. automethod:: set_channel + .. automethod:: set_child + .. autoattribute:: addr_list AddrListStruct class -------------------- @@ -34,7 +42,9 @@ successful connection to a child node. easily pass an instantiated `AddrListStruct` object to the :py:func:`print()` function. .. autoclass:: pyrf24.rf24_mesh.AddrListStruct - :members: + + .. autoattribute:: node_id + .. autoattribute:: address Mesh Constants ---------------- diff --git a/docs/rf24_network_api.rst b/docs/rf24_network_api.rst index 09f48df..f558649 100644 --- a/docs/rf24_network_api.rst +++ b/docs/rf24_network_api.rst @@ -8,22 +8,29 @@ RF24Network API RF24Network class ----------------- -Basic RF24Network API -********************* .. autoclass:: pyrf24.rf24_network.RF24Network - :members: begin, update, available, peek, read, write, node_address - :special-members: __init__ - -Advanced RF24Network API -************************ - -.. automethod:: pyrf24.rf24_network.RF24Network.multicast -.. automethod:: pyrf24.rf24_network.RF24Network.is_address_valid -.. autoattribute:: pyrf24.rf24_network.RF24Network.multicast_relay -.. autoattribute:: pyrf24.rf24_network.RF24Network.tx_timeout -.. autoattribute:: pyrf24.rf24_network.RF24Network.route_timeout -.. autoattribute:: pyrf24.rf24_network.RF24Network.multicast_level + + Basic RF24Network API + ********************* + + .. automethod:: begin + .. automethod:: update + .. automethod:: available + .. automethod:: peek + .. automethod:: read + .. automethod:: write + .. autoattribute:: node_address + + Advanced RF24Network API + ************************ + + .. automethod:: multicast + .. automethod:: is_address_valid + .. autoattribute:: multicast_relay + .. autoattribute:: tx_timeout + .. autoattribute:: route_timeout + .. autoattribute:: multicast_level External Systems or Applications ******************************** @@ -39,8 +46,13 @@ RF24NetworkHeader class easily pass an instantiated `RF24NetworkHeader` object to the :py:func:`print()` function. .. autoclass:: pyrf24.rf24_network.RF24NetworkHeader - :members: to_node, type, from_node, id, reserved, to_string - :special-members: __init__ + + .. autoattribute:: to_node + .. autoattribute:: type + .. autoattribute:: from_node + .. autoattribute:: id + .. autoattribute:: reserved + .. autoattribute:: to_string .. property:: next_id :classmethod: diff --git a/examples/scanner.py b/examples/scanner.py index 5afb944..cb72060 100644 --- a/examples/scanner.py +++ b/examples/scanner.py @@ -29,9 +29,12 @@ # use reverse engineering tactics for a better "snapshot" radio.address_width = 2 -radio.open_rx_pipe(1, b"\0\x55") -radio.open_rx_pipe(0, b"\0\xAA") - +radio.open_rx_pipe(0, b"\x55\x55") +radio.open_rx_pipe(1, b"\xAA\xAA") +radio.open_rx_pipe(2, b"\xA0\xAA") +radio.open_rx_pipe(3, b"\x0A\xAA") +radio.open_rx_pipe(4, b"\xA5\xAA") +radio.open_rx_pipe(5, b"\x5A\xAA") def scan(timeout: int = 30): """Traverse the spectrum of accessible frequencies and print any detection @@ -53,12 +56,17 @@ def scan(timeout: int = 30): start_timer = time.monotonic() # start the timer while time.monotonic() - start_timer < timeout: radio.channel = curr_channel - if radio.available(): - radio.flush_rx() # flush the RX FIFO because it asserts the RPD flag radio.listen = 1 # start a RX session time.sleep(0.00013) # wait 130 microseconds - signals[curr_channel] += radio.rpd # if interference is present + found_signal = radio.rpd radio.listen = 0 # end the RX session + found_signal = found_signal or radio.rpd or radio.available() + + # count signal as interference + signals[curr_channel] += found_signal + # clear the RX FIFO if a signal was detected/captured + if found_signal: + radio.flush_rx() # flush the RX FIFO because it asserts the RPD flag curr_channel = curr_channel + 1 if curr_channel < 125 else 0 # output the signal counts per channel diff --git a/pybind11 b/pybind11 index ffa3468..aa304c9 160000 --- a/pybind11 +++ b/pybind11 @@ -1 +1 @@ -Subproject commit ffa346860b306c9bbfb341aed9c14c067751feb8 +Subproject commit aa304c9c7d725ffb9d10af08a3b34cb372307020 diff --git a/pyproject.toml b/pyproject.toml index 404b1ff..669f58c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,22 @@ [build-system] +# building cmake from pypi releases requires openssl-dev installed, so +# just require users install cmake from apt when getting python-dev (CPython headers) requires = [ "setuptools>=45", "wheel", "pybind11>=2.7.1; sys_platform == 'linux'", "scikit-build; sys_platform == 'linux'", - "cmake; sys_platform == 'linux'", - "ninja; sys_platform == 'linux'", "setuptools_scm>=6.2" ] build-backend = "setuptools.build_meta" [tool.setuptools_scm] +# pypi does not accept version strings with commit SHA in it. See PEP440 +local_scheme = "no-local-version" +fallback_version = "0.0.0" +version_scheme = "no-guess-dev" + +[tool.mypy] +show_error_codes = true +pretty = true diff --git a/setup.py b/setup.py index debd76b..769e3f0 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,6 @@ """Build & Install script for the pyrf24 package or python wrappers about the RF24 C++ libraries.""" +from typing import List import platform IS_LINUX = platform.system().title() == "Linux" @@ -14,26 +15,26 @@ long_description = file_handle.read() -def exclude_rf24_utility_folder(cmake_manifest): +def exclude_rf24_utility_folder(cmake_manifest: List[str]): """Exclude unnecessary header files from the built python pkg.""" return list(filter(lambda name: not (name.endswith(".h")), cmake_manifest)) -kwargs = { - "name": "pyrf24", - "author": "2bndy5", - "author_email": "2bndy5@gmail.com", - "description": "A python package for the wrapping nRF24 related C++ libraries", - "long_description": long_description, - "long_description_content_type": "text/x-rst", - "url": "https://github.com/nRF24/pyRF24", - "packages": ["pyrf24"], - "package_data": {"pyrf24": ["rf24.pyi", "rf24_network.pyi", "rf24_mesh.pyi"]}, - "package_dir": {"": "src"}, - "zip_safe": False, - "license": "GNU General Public License v2 (GPLv2)", - "classifiers": [ - "Development Status :: 3 - Beta", # TODO change this when ready +setup_args = dict( + name="pyrf24", + author="2bndy5", + author_email="2bndy5@gmail.com", + description="A python package for the wrapping nRF24 related C++ libraries", + long_description=long_description, + long_description_content_type="text/x-rst", + url="https://github.com/nRF24/pyRF24", + packages=["pyrf24"], + package_data={"pyrf24": ["rf24.pyi", "rf24_network.pyi", "rf24_mesh.pyi"]}, + package_dir={"": "src"}, + zip_safe=False, + license="GNU General Public License v2 (GPLv2)", + classifiers=[ + "Development Status :: 4 - Beta", # TODO change this when ready "Intended Audience :: Developers", "Topic :: Software Development :: Libraries", "Topic :: System :: Hardware", @@ -41,18 +42,18 @@ def exclude_rf24_utility_folder(cmake_manifest): "License :: OSI Approved :: GNU General Public License v2 (GPLv2)", "Operating System :: POSIX :: Linux", ], - "python_requires": ">=3.7", - "keywords": "nrf24l01 nRF24L01+ raspberry pi driver radio transceiver", + python_requires=">=3.7", + keywords="nrf24l01 nRF24L01+ raspberry pi driver radio transceiver", # Extra links for the sidebar on pypi - "project_urls": { + project_urls={ "Documentation": "http://nRF24.github.io/pyRF24", }, - "download_url": "https://github.com/nRF24/pyRF24/releases", -} + download_url="https://github.com/nRF24/pyRF24/releases", +) if IS_LINUX: - kwargs["cmake_install_dir"] = "src/pyrf24" - kwargs["cmake_args"] = ["-DRF24_DRIVER=SPIDEV"] - kwargs["cmake_process_manifest_hook"] = exclude_rf24_utility_folder + setup_args["cmake_install_dir"] = "src/pyrf24" + setup_args["cmake_args"] = ["-DRF24_DRIVER=SPIDEV"] + setup_args["cmake_process_manifest_hook"] = exclude_rf24_utility_folder -setup(**kwargs) +setup(**setup_args) diff --git a/src/pyrf24/fake_ble.py b/src/pyrf24/fake_ble.py index a97e229..c9c4971 100644 --- a/src/pyrf24/fake_ble.py +++ b/src/pyrf24/fake_ble.py @@ -76,7 +76,7 @@ # pylint: disable=too-few-public-methods,missing-docstring,too-many-instance-attributes from os import urandom import struct -from typing import Union, List +from typing import Union, List, Optional from .rf24 import ( # pylint: disable=import-error RF24, RF24_CRC_DISABLED, @@ -134,7 +134,7 @@ def swap_bits(original: int) -> int: return reverse -def reverse_bits(original: bytearray) -> bytearray: +def reverse_bits(original: Union[bytes, bytearray]) -> bytearray: """This function reverses the bit order for an entire buffer protocol object. :returns: @@ -275,17 +275,17 @@ class QueueElement: def __init__(self, buffer: Union[bytes, bytearray]): #: The transmitting BLE device's MAC address as a `bytes` object. self.mac: bytes = bytes(buffer[2:8]) - self.name: bytes = None + self.name: Optional[Union[bytes, str]] = None """The transmitting BLE device's name. This will be a `str`, `bytes` object (if a `UnicodeError` was caught), or `None` (if not included in the received payload).""" - self.pa_level: int = None + self.pa_level: Optional[int] = None """The transmitting device's PA Level (if included in the received payload) as an `int`. .. note:: This value does not represent the received signal strength. The nRF24L01 will receive anything over a -64 dbm threshold.""" - self.data: List[Union[bytearray, bytes, ServiceData]] = [] + self.data: List[Union[bytearray, bytes, ServiceDataType]] = [] """A `list` of the transmitting device's data structures (if any). If an element in this `list` is not an instance (or descendant) of the `ServiceData` class, then it is likely a custom, user-defined, or unsupported @@ -320,18 +320,19 @@ def _decode_data_struct(self, buf: Union[bytes, bytearray]) -> bool: self.data.append(buf) # return the raw buffer as a value if buf[0] == 0x16: # if it is service data service_data_uuid = struct.unpack(" bool: self.rx_queue.append(QueueElement(self.rx_cache)) return bool(self.rx_queue) - def read(self) -> QueueElement: + def read(self) -> Optional[QueueElement]: """Get the First Out element from the queue. :Returns: @@ -705,12 +706,12 @@ def uuid(self) -> bytes: return self._type @property - def data(self) -> bytes: + def data(self) -> Union[float, int, str, bytes, bytearray]: """This attribute is a `bytearray` or `bytes` object.""" return self._data @data.setter - def data(self, value): + def data(self, value: Union[float, int, str, bytes, bytearray]): self._data = value @property @@ -752,7 +753,7 @@ def data(self) -> float: return struct.unpack(" int: return int(self._data[0]) @data.setter - def data(self, value: int): + def data(self, value: Union[bytes, bytearray, int]): if isinstance(value, int): self._data = struct.pack("B", value) elif isinstance(value, (bytes, bytearray)): @@ -817,7 +818,7 @@ def pa_level_at_1_meter(self) -> int: return struct.unpack(">b", self._type[-1:])[0] @pa_level_at_1_meter.setter - def pa_level_at_1_meter(self, value): + def pa_level_at_1_meter(self, value: Union[bytes, bytearray, int]): if isinstance(value, int): self._type = self._type[:-1] + struct.pack(">b", int(value)) elif isinstance(value, (bytes, bytearray)): @@ -838,7 +839,7 @@ def data(self) -> str: return value @data.setter - def data(self, value: str): + def data(self, value: Union[bytes, bytearray, str]): if isinstance(value, str): for i, b_code in enumerate(UrlServiceData.codex_prefix): value = value.replace(b_code, chr(i), 1) @@ -850,3 +851,7 @@ def data(self, value: str): def __repr__(self) -> str: return "Advertised URL: " + self.data + + +# A type alias to explain the funky inheritance +ServiceDataType = Union[BatteryServiceData, TemperatureServiceData, UrlServiceData] diff --git a/src/pyrf24/pyRF24.cpp b/src/pyrf24/pyRF24.cpp index 70480b7..4c062c1 100644 --- a/src/pyrf24/pyRF24.cpp +++ b/src/pyrf24/pyRF24.cpp @@ -145,17 +145,6 @@ class RF24Wrapper : public RF24 static_cast(get_bytes_or_bytearray_ln(buf))); } - // complete FIFO info helper; this replaces isRxFifoFull() - uint8_t is_fifo(const bool about_tx) - { - return static_cast((read_register(FIFO_STATUS) >> (4 * about_tx)) & 3); - } - - bool is_fifo(const bool about_tx, const bool check_empty) - { - return static_cast(is_fifo(about_tx) & _BV(!check_empty)); - } - char* sprintfDetails() { char* debug_info = new char[870]; @@ -530,7 +519,7 @@ PYBIND11_MODULE(rf24, m) )docstr") // ***************************************************************************** - + .def("stopListening", &RF24Wrapper::stopListening, R"docstr( stopListening() @@ -703,7 +692,8 @@ PYBIND11_MODULE(rf24, m) .. seealso:: Values accepted by the parameter are predefined in the `rf24_crclength_e` enum struct. - )docstr", py::arg("length")) + )docstr", + py::arg("length")) // ***************************************************************************** @@ -711,7 +701,8 @@ PYBIND11_MODULE(rf24, m) setChannel(channel: int) Set the current setting of the radio's channel. - )docstr", py::arg("channel")) + )docstr", + py::arg("channel")) // ***************************************************************************** @@ -722,7 +713,8 @@ PYBIND11_MODULE(rf24, m) :param rf24_datarate_e rate: The speed in which the radio send out data over the air. Values accepted for this parameter are pre-defined in the `rf24_datarate_e` enum struct. - )docstr", py::arg("rate")) + )docstr", + py::arg("rate")) // ***************************************************************************** @@ -733,7 +725,8 @@ PYBIND11_MODULE(rf24, m) :param int width: The number of bytes used for address' length assigned to the data pipes. Accepted values are clamped to range [3, 5]. - )docstr", py::arg("width")) + )docstr", + py::arg("width")) // ***************************************************************************** @@ -781,7 +774,8 @@ PYBIND11_MODULE(rf24, m) :param rf24_pa_dbm_e level: The value used to configure Power Amplitude level. Accepted values are pre-defined in the `rf24_pa_dbm_e` enum struct. :param int channel: The channel to broadcast on. - )docstr") + )docstr", + py::arg("level"), py::arg("channel")) .def("startConstCarrier", &RF24Wrapper::startConstCarrier, R"docstr( startConstCarrier(level: rf24_pa_dbm_e, channel: int) @@ -1002,7 +996,8 @@ PYBIND11_MODULE(rf24, m) Configure the radio's static payload size (outgoing and incoming) for all data pipes. :param int length: The length of static payloads used for all data pipes. - )docstr", py::arg("length")) + )docstr", + py::arg("length")) // ***************************************************************************** @@ -1038,8 +1033,10 @@ PYBIND11_MODULE(rf24, m) // ***************************************************************************** - .def("is_fifo", static_cast(&RF24Wrapper::is_fifo), R"docstr( - is_fifo(about_tx: bool, check_empty: bool = None) -> Union[bool, int] + .def("is_fifo", static_cast(&RF24Wrapper::isFifo), R"docstr( + is_fifo(about_tx: bool, check_empty: bool) -> bool \ + is_fifo(about_tx: bool) -> int + Get information about a specified FIFO buffers. @@ -1050,9 +1047,14 @@ PYBIND11_MODULE(rf24, m) )docstr", py::arg("about_tx"), py::arg("check_empty")) + .def("isFifo", static_cast(&RF24Wrapper::isFifo), R"docstr( + isFifo(about_tx: bool, check_empty: bool) -> bool + )docstr", + py::arg("about_tx"), py::arg("check_empty")) + // ***************************************************************************** - .def("is_fifo", static_cast(&RF24Wrapper::is_fifo), R"docstr( + .def("is_fifo", static_cast(&RF24Wrapper::isFifo), R"docstr( :Returns: - A `bool` describing if the specified FIFO is empty or full. - An `int` if the ``check_empty`` parameter was unspecified. In which case, the return integer is @@ -1063,6 +1065,11 @@ PYBIND11_MODULE(rf24, m) )docstr", py::arg("about_tx")) + .def("isFifo", static_cast(&RF24Wrapper::isFifo), R"docstr( + isFifo(about_tx: bool) -> int + )docstr", + py::arg("about_tx")) + // ***************************************************************************** // *********************************** functions wrapped into python object's properties @@ -1107,6 +1114,9 @@ PYBIND11_MODULE(rf24, m) This attribute represents the radio's CRC checksum length (in bits). .. seealso:: Accepted values are predefined in the `rf24_crclength_e` enum struct. + .. note:: + The radio automatically uses CRC checksums when the auto-ack feature is enabled. + This attribute may not reflect this situation if CRC is disabled when auto-ack is enabled. )docstr") // ***************************************************************************** @@ -1151,8 +1161,7 @@ PYBIND11_MODULE(rf24, m) .. note:: Since `ack_payloads` requires Dynamic Payload lengths, - `ack_payloads` are also disabled when setting this attribute - to `False`. + `ack_payloads` are also disabled when setting this attribute is set to `False`. )docstr") // ***************************************************************************** @@ -1205,13 +1214,13 @@ PYBIND11_MODULE(rf24, m) // ***************************************************************************** .def_property_readonly("is_plus_variant", &RF24Wrapper::isPVariant, R"docstr( - This read-only attribute represents if the detected radio is a nRF24L01+ model. + This read-only `bool` attribute represents if the detected radio is a nRF24L01+ model. )docstr") // ***************************************************************************** .def_property_readonly("rpd", &RF24Wrapper::testRPD, R"docstr( - This attribute represents if the radio detected a signal above -64 dbm in RX mode. + This read-only `bool` attribute represents if the radio detected a signal above -64 dbm in RX mode. .. hint:: RPD stands for "Received Power Detection". Non-plus variants of nRF24L01 @@ -1222,19 +1231,19 @@ PYBIND11_MODULE(rf24, m) // ***************************************************************************** .def_property_readonly("rx_fifo_full", &RF24Wrapper::rxFifoFull, R"docstr( - This attribute represents if all 3 levels of the radio's RX FIFO are occupied. + This `bool` attribute represents if all 3 levels of the radio's RX FIFO are occupied. )docstr") // ***************************************************************************** .def_readwrite("cs_delay", &RF24Wrapper::csDelay, R"docstr( - The number of microseconds used as a delay when the radio's CSN pin is made active. + The `int` number of microseconds used as a delay when the radio's CSN pin is made active. )docstr") // ***************************************************************************** .def_property_readonly("is_chip_connected", &RF24Wrapper::isChipConnected, R"docstr( - Check if the SPI bus is working with the radio. This attribute assumes that + Check if the SPI bus is working with the radio. This read-only `bool` attribute assumes that :py:meth:`~pyrf24.rf24.RF24.begin()` returned `True`. )docstr") @@ -1242,6 +1251,23 @@ PYBIND11_MODULE(rf24, m) isChipConnected() -> bool )docstr") + // ***************************************************************************** + + .def_readwrite("tx_delay", &RF24Wrapper::txDelay, R"docstr( + The driver will delay for this duration (`int` in microseconds) when `listen` is set to `False`. + + When responding to payloads, faster devices like ARM(RPi) are much faster than Arduino: + + 1. Arduino sends data to RPi, switches to RX mode + 2. The RPi receives the data, switches to TX mode and sends before the Arduino radio is in RX mode + 3. If AutoACK is disabled, this can be set as low as 0. If AutoACK enabled, set to 100uS minimum on RPi + + .. warning:: + If set to 0, ensure 130uS delay after `listen` is set to `False` before any transmitting. + )docstr") + + .def_readwrite("txDelay", &RF24Wrapper::txDelay) + // ***************************************************************************** // **************** functions that accept python's buffer protocol objects (bytes, bytearray) @@ -1383,6 +1409,5 @@ PYBIND11_MODULE(rf24, m) .def("writeFast", &RF24Wrapper::writeFast, R"docstr( writeFast(buf: Union[bytearray, bytes], multicast: bool = False) -> bool )docstr", - py::arg("buf"), py::arg("multicast") = false) - ; + py::arg("buf"), py::arg("multicast") = false); } diff --git a/src/pyrf24/pyRF24Mesh.cpp b/src/pyrf24/pyRF24Mesh.cpp index 0601513..7d1909b 100644 --- a/src/pyrf24/pyRF24Mesh.cpp +++ b/src/pyrf24/pyRF24Mesh.cpp @@ -155,17 +155,17 @@ PYBIND11_MODULE(rf24_mesh, m) mesh networks' :attr:`~pyrf24.rf24_mesh.RF24Mesh.addr_list` list. .. code-block:: py - + # Set a static address for node 0o2, with nodeID 23, since it will just be # a static routing node for example running on an ATTiny chip. mesh.setAddress(23, 0o2); - + .. code-block:: py - + # Change or set the nodeID for an existing address address = 0o12; mesh.setAddress(3, address, True); - + :param int node_id: The unique identifying number for the connected node. :param int address: The `Logical Address ` for the connected node. :param bool search_by_address: Set this parameter to `True` traverse the list of @@ -237,7 +237,7 @@ PYBIND11_MODULE(rf24_mesh, m) The read-only attribute returns a `list` of addresses assigned to nodes' ID numbers. Each element is a `AddrListStruct` object. This attribute should only be used on the master node. - .. important:: + .. important:: Altering any values for elements contained in this list is prohibited. Use `set_address()` instead. )docstr") @@ -264,7 +264,7 @@ PYBIND11_MODULE(rf24_mesh, m) .def("setNodeID", &RF24MeshWrapper::setNodeID, R"docstr( setNodeID(nodeID: int) - + Configure the `node_id` attribute. )docstr", py::arg("nodeID")) diff --git a/src/pyrf24/pyRF24Network.cpp b/src/pyrf24/pyRF24Network.cpp index a8e47bc..707233f 100644 --- a/src/pyrf24/pyRF24Network.cpp +++ b/src/pyrf24/pyRF24Network.cpp @@ -6,7 +6,7 @@ namespace py = pybind11; -/* +/* namespace pybind11 { namespace detail { @@ -486,12 +486,12 @@ PYBIND11_MODULE(rf24_network, m) .. csv-table:: :header: Message Name, Numeric Value, Additional Context - :py:attr:`~pyrf24.rf24_network.NETWORK_ADDR_RESPONSE`, 128, + :py:attr:`~pyrf24.rf24_network.NETWORK_ADDR_RESPONSE`, 128, :py:attr:`~pyrf24.rf24_network.NETWORK_ACK`, 193, :py:attr:`~pyrf24.rf24_network.NETWORK_PING`, 130, :py:attr:`~pyrf24.rf24_network.NETWORK_POLL`, 194, With multicast enabled (which is enabled by default) :py:attr:`~pyrf24.rf24_network.NETWORK_REQ_ADDRESS`, 195, - + .. seealso:: There's a more complete list (with behavioral descriptions) of the :ref:`reserved_sys_msgs`. )docstr") diff --git a/src/pyrf24/rf24.pyi b/src/pyrf24/rf24.pyi index 69bd72a..8d16695 100644 --- a/src/pyrf24/rf24.pyi +++ b/src/pyrf24/rf24.pyi @@ -2,33 +2,33 @@ from typing import Tuple, Union, overload class rf24_crclength_e: - RF24_CRC_DISABLED: int = 0 - RF24_CRC_8: int = 1 - RF24_CRC_16: int = 2 + RF24_CRC_DISABLED: "rf24_crclength_e" + RF24_CRC_8: "rf24_crclength_e" + RF24_CRC_16: "rf24_crclength_e" -RF24_CRC_DISABLED: int = rf24_crclength_e.RF24_CRC_DISABLED -RF24_CRC_8: int = rf24_crclength_e.RF24_CRC_8 -RF24_CRC_16: int = rf24_crclength_e.RF24_CRC_16 +RF24_CRC_DISABLED: rf24_crclength_e = rf24_crclength_e.RF24_CRC_DISABLED +RF24_CRC_8: rf24_crclength_e = rf24_crclength_e.RF24_CRC_8 +RF24_CRC_16: rf24_crclength_e = rf24_crclength_e.RF24_CRC_16 class rf24_datarate_e: - RF24_1MBPS: int = 0 - RF24_2MBPS: int = 1 - RF24_250KBPS: int = 2 + RF24_1MBPS: rf24_datarate_e + RF24_2MBPS: rf24_datarate_e + RF24_250KBPS: rf24_datarate_e -RF24_1MBPS: int = rf24_datarate_e.RF24_1MBPS -RF24_2MBPS: int = rf24_datarate_e.RF24_2MBPS -RF24_250KBPS: int = rf24_datarate_e.RF24_250KBPS +RF24_1MBPS: rf24_datarate_e = rf24_datarate_e.RF24_1MBPS +RF24_2MBPS: rf24_datarate_e = rf24_datarate_e.RF24_2MBPS +RF24_250KBPS: rf24_datarate_e = rf24_datarate_e.RF24_250KBPS class rf24_pa_dbm_e: - RF24_PA_MIN: int = 0 - RF24_PA_LOW: int = 1 - RF24_PA_HIGH: int = 2 - RF24_PA_MAX: int = 3 + RF24_PA_MIN: rf24_pa_dbm_e + RF24_PA_LOW: rf24_pa_dbm_e + RF24_PA_HIGH: rf24_pa_dbm_e + RF24_PA_MAX: rf24_pa_dbm_e -RF24_PA_MIN: int = rf24_pa_dbm_e.RF24_PA_MIN -RF24_PA_LOW: int = rf24_pa_dbm_e.RF24_PA_LOW -RF24_PA_HIGH: int = rf24_pa_dbm_e.RF24_PA_HIGH -RF24_PA_MAX: int = rf24_pa_dbm_e.RF24_PA_MAX +RF24_PA_MIN: rf24_pa_dbm_e = rf24_pa_dbm_e.RF24_PA_MIN +RF24_PA_LOW: rf24_pa_dbm_e = rf24_pa_dbm_e.RF24_PA_LOW +RF24_PA_HIGH: rf24_pa_dbm_e = rf24_pa_dbm_e.RF24_PA_HIGH +RF24_PA_MAX: rf24_pa_dbm_e = rf24_pa_dbm_e.RF24_PA_MAX class RF24: @overload @@ -63,6 +63,7 @@ class RF24: def isPVariant(self) -> bool: ... def isValid(self) -> bool: ... def is_fifo(self, about_tx: bool, check_empty: bool = None) -> Union[bool, int]: ... + def isFifo(self, about_tx: bool, check_empty: bool = None) -> Union[bool, int]: ... def mask_irq(self, tx_ok: bool, tx_fail: bool, rx_ready: bool) -> None: ... def maskIRQ(self, tx_ok: bool, tx_fail: bool, rx_ready: bool) -> None: ... def open_tx_pipe(self, address: Union[bytes, bytearray]) -> None: ... @@ -159,13 +160,17 @@ class RF24: @channel.setter def channel(self, value: int) -> None: ... @property - def crc_length(self) -> int: ... + def crc_length(self) -> rf24_crclength_e: ... @crc_length.setter def crc_length(self, value: rf24_crclength_e) -> None: ... @property - def cs_delay(self) -> int: ... - @cs_delay.setter - def cs_delay(self, value: int) -> None: ... + def tx_delay(self) -> int: ... + @tx_delay.setter + def tx_delay(self, value: int) -> None: ... + @property + def txDelay(self) -> int: ... + @txDelay.setter + def txDelay(self, value: int) -> None: ... @property def data_rate(self) -> int: ... @data_rate.setter diff --git a/src/pyrf24/rf24_network.pyi b/src/pyrf24/rf24_network.pyi index f771e76..b423c0e 100644 --- a/src/pyrf24/rf24_network.pyi +++ b/src/pyrf24/rf24_network.pyi @@ -46,7 +46,7 @@ class RF24NetworkHeader: @property def next_id(self) -> int: ... -# RF24NetworkFrame is not exposed as is not needed +# RF24NetworkFrame is not exposed as it is not needed # class RF24NetworkFrame: # def __init__( # self, header: RF24NetworkHeader = None, message: Union[bytes, bytearray] = None @@ -138,4 +138,4 @@ class RF24Network: @txTimeout.setter def txTimeout(self, timeout: int) -> int: ... # @property - # def external_queue(self) -> List[RF24NetworkFrame]: ... \ No newline at end of file + # def external_queue(self) -> List[RF24NetworkFrame]: ...