diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f1ece3c..da17e86 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,12 +11,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: 3.x - name: Checkout Current Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: true fetch-depth: 0 @@ -74,7 +74,7 @@ jobs: publish_dir: ./docs/_build/html - name: Save distributable wheels as artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: "pyRF24_pkg_dist" path: ${{ github.workspace }}/dist diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 19350d1..aeeac58 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,12 +10,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Set up Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: - python-version: 3.9 + python-version: 3.x - name: Checkout Current Repo - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: true fetch-depth: 0 @@ -33,10 +33,10 @@ jobs: platforms: aarch64 - name: Build wheels with cibuildwheels - uses: pypa/cibuildwheel@v2.8.1 + uses: pypa/cibuildwheel@v2.12.0 env: CIBW_ARCHS_LINUX: aarch64 native - CIBW_SKIP: cp36* pp* cp311* *musllinux* + CIBW_SKIP: cp36* pp* *musllinux* - name: Move cross-compiled wheels to dist folder run: | @@ -48,7 +48,7 @@ jobs: run: python setup.py sdist - name: Save distributable wheels as artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: "pyRF24_pkg_dist" path: ${{ github.workspace }}/dist diff --git a/README.rst b/README.rst index ee87ac0..69c8c08 100644 --- a/README.rst +++ b/README.rst @@ -15,7 +15,7 @@ Introduction ============ This is the official home of the python wrappers for the RF24 stack. It is meant for Linux-based -SoC boards like the Raspberry Pi. +SoC boards like the Raspberry Pi. Documentation is hosted at http://pyrf24.rtfd.io/. Pinout ~~~~~~ @@ -25,7 +25,7 @@ Pinout The nRF24L01's CE and IRQ pins can be connected to other GPIO pins on the SoC. The MISO, MOSI, SCK are limited to the corresponding counterparts on the SoC's SPI bus. The CSN pin is limited to the -chosen SPI bus's "Chip Select" options (Also labeled as "CE" pins on many Raspberry Pi pinout +chosen SPI bus's "Chip Select" options (also labeled as "CE" pins on many Raspberry Pi pinout diagrams). The following table shows the default pins used in all the `examples `_ for this package. @@ -274,7 +274,9 @@ in various development environments. Documentation ~~~~~~~~~~~~~ -Before submitting contributions, you should make sure that any documentation changes builds +Each release has corresponding documentation hosted at http://pyrf24.rtfd.io/. + +Before submitting contributions, you should make sure that any documentation changes build successfully. This can be done locally but **on Linux only**. The documentation of API requires this package (& all its latest changes) be installed. diff --git a/RF24 b/RF24 index 89358b2..d7c4041 160000 --- a/RF24 +++ b/RF24 @@ -1 +1 @@ -Subproject commit 89358b2df7de37d64f2bba180d61b6d200c54070 +Subproject commit d7c4041f001a7fbc880535f5151f89a56a520072 diff --git a/RF24Mesh b/RF24Mesh index 105386b..1b6de15 160000 --- a/RF24Mesh +++ b/RF24Mesh @@ -1 +1 @@ -Subproject commit 105386baa2a13e24e595c1bd4f173b353b6c9f26 +Subproject commit 1b6de15ebc4fd5a405b442e4dff432936bc80967 diff --git a/RF24Network b/RF24Network index 122cb6c..fc2fc50 160000 --- a/RF24Network +++ b/RF24Network @@ -1 +1 @@ -Subproject commit 122cb6c399c577dac87ae196a9f6063e3c95164c +Subproject commit fc2fc50e951772b34c7d18725de45adfe407a2bc diff --git a/docs/_static/custom_material.css b/docs/_static/custom_material.css index 0f63e2c..ced617b 100644 --- a/docs/_static/custom_material.css +++ b/docs/_static/custom_material.css @@ -1,51 +1,3 @@ -.md-typeset .admonition, -.md-typeset details { - font-size: 0.75rem; -} - -.md-typeset .admonition.tip>.admonition-title::before, -.md-typeset .admonition.hint>.admonition-title::before { - mask-image: url('data:image/svg+xml;charset=utf-8,'); -} - -.md-typeset .admonition.seealso>.admonition-title::before { - mask-image: url('data:image/svg+xml;charset=utf-8,'); - background-color: hsl(301, 100%, 63%); -} - -.md-typeset .admonition.seealso { - border-left: .2rem solid hsl(301, 100%, 63%); -} - -.md-typeset .admonition.seealso>.admonition-title { - background-color: hsla(287, 100%, 63%, 0.25); -} - -.md-typeset .admonition.important>.admonition-title::before { - mask-image: url('data:image/svg+xml;charset=utf-8,'); - background-color: hsl(123, 100%, 63%); -} - -.md-typeset .admonition.important { - border-left: .2rem solid hsl(123, 100%, 63%); -} - -.md-typeset .admonition.important>.admonition-title { - background-color: hsla(123, 100%, 63%, 0.25); -} - -.md-typeset .admonition.warning>.admonition-title::before { - background-color: hsl(0, 100%, 63%); -} - -.md-typeset .admonition.warning { - border-left: .2rem solid hsl(0, 100%, 63%); -} - -.md-typeset .admonition.warning>.admonition-title { - background-color: hsla(0, 100%, 63%, 0.25); -} - html .md-nav--primary .md-nav__title--site .md-nav__button { top: 0; left: 0; @@ -54,8 +6,8 @@ html .md-nav--primary .md-nav__title--site .md-nav__button { } thead { - background-color: var(--md-default-fg-color--light); - color: var(--md-primary-bg-color); + background-color: var(--md-default-fg-color--light); + color: var(--md-primary-bg-color); } .md-nav__title .md-nav__button.md-logo img, .md-nav__title .md-nav__button.md-logo svg { @@ -66,23 +18,3 @@ thead { .md-header__button.md-logo img, .md-header__button.md-logo svg { width: auto; } - -/* CSS for Remark admonitions (translated by breathe from doxygen's @remark(s) cmd */ -:root { - --md-admonition-icon--remark: url('data:image/svg+xml;charset=utf-8,') -} - -.md-typeset .admonition.remark { - border-color: rgb(116, 66, 255); -} - -.md-typeset .remark > .admonition-title { - background-color: rgba(116, 66, 255, 0.1); - border-color: rgb(116, 66, 255); -} - -.md-typeset .remark > .admonition-title::before { - background-color: rgb(116, 66, 255); - -webkit-mask-image: var(--md-admonition-icon--remark); - mask-image: var(--md-admonition-icon--remark); -} diff --git a/docs/conf.py b/docs/conf.py index 9ae389a..95038bd 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -107,6 +107,42 @@ ("py:parameter", dict(include_in_toc=False)), ] +sphinx_immaterial_custom_admonitions = [ + { + "name": "warning", + "color": (255, 66, 66), + "icon": "octicons/alert-24", + "override": True, + }, + { + "name": "note", + "icon": "octicons/pencil-24", + "override": True, + }, + { + "name": "seealso", + "color": (255, 66, 252), + "icon": "octicons/eye-24", + "title": "See Also", + "override": True, + }, + { + "name": "hint", + "icon": "material/school", + "override": True, + }, + { + "name": "tip", + "icon": "material/school", + "override": True, + }, + { + "name": "important", + "icon": "material/school", + "override": True, + }, +] + python_type_aliases = { "pyrf24.rf24.rf24_datarate_e": "rf24_datarate_e", } diff --git a/docs/requirements.txt b/docs/requirements.txt index d078f24..83c9efd 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1 +1,2 @@ +sphinx<6.0 sphinx-immaterial diff --git a/pybind11 b/pybind11 index aa304c9..0bd8896 160000 --- a/pybind11 +++ b/pybind11 @@ -1 +1 @@ -Subproject commit aa304c9c7d725ffb9d10af08a3b34cb372307020 +Subproject commit 0bd8896a4010f2d91b2340570c24fa08606ec406 diff --git a/requirements-dev.txt b/requirements-dev.txt index 17ff0f2..dc5c8a6 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,3 +1,4 @@ pylint mypy -cpp-linter \ No newline at end of file +cpp-linter +black diff --git a/src/pyRF24.cpp b/src/pyRF24.cpp index a426739..18787da 100644 --- a/src/pyRF24.cpp +++ b/src/pyRF24.cpp @@ -1097,7 +1097,7 @@ PYBIND11_MODULE(rf24, m) // ***************************************************************************** .def_property("payload_size", &RF24Wrapper::getPayloadSize, &RF24Wrapper::setPayloadSize, R"docstr( - This `int` attribute represents the radio's static payload lengths. + This `int` attribute represents the radio's static payload lengths. Maximum length is 32 bytes; minimum is 1 byte. .. note:: This attribute is only used when the radio's `dynamic_payloads` feature is disabled (which is disabled by default). diff --git a/src/pyRF24Network.cpp b/src/pyRF24Network.cpp index 346915d..3d91ed6 100644 --- a/src/pyRF24Network.cpp +++ b/src/pyRF24Network.cpp @@ -60,10 +60,10 @@ class RF24NetworkWrapper : public RF24Network return RF24Network::peek(header); } - std::tuple peek_frame(uint8_t maxlen = MAX_PAYLOAD_SIZE) + std::tuple peek_frame(uint16_t maxlen = MAX_PAYLOAD_SIZE) { RF24NetworkHeader header; - maxlen = static_cast(rf24_min(maxlen, RF24Network::peek(header))); + maxlen = static_cast(rf24_min(maxlen, RF24Network::peek(header))); char* buf = new char[maxlen + 1]; RF24Network::peek(header, buf, maxlen); py::bytearray py_ba = py::bytearray(buf, maxlen); @@ -326,12 +326,13 @@ PYBIND11_MODULE(rf24_network, m) // ***************************************************************************** .def("read", &RF24NetworkWrapper::read, R"docstr( - read(maxlen: int = 144) -> Tuple[RF24NetworkHeader, bytearray] + read(maxlen: int = MAX_PAYLOAD_SIZE) -> Tuple[RF24NetworkHeader, bytearray] Fetch the next available frame received by the network node. This differs from `peek()` as it removes the frame from the queue. - :param int maxlen: The maximum length of the frame's message to be returned. If this parameter is unspecified, then the entire - length of the frame's message is returned. + :param int maxlen: The maximum length of the frame's message to be returned. If this parameter is unspecified or greater than + the actual frame's message size, then only the frame's full message size is used. Defaults to + :py:attr:`~pyrf24.rf24_network.MAX_PAYLOAD_SIZE`. :Returns: A `tuple` in which @@ -344,7 +345,7 @@ PYBIND11_MODULE(rf24_network, m) .def("peek", &RF24NetworkWrapper::peek_header, R"docstr( peek(header: RF24NetworkHeader) -> int \ - peek(maxlen: int) -> Tuple[RF24NetworkHeader, bytearray] + peek(maxlen: int = MAX_PAYLOAD_SIZE) -> Tuple[RF24NetworkHeader, bytearray] To fetch the next available frame's header received by the network node, the parameter and return type is as follows: :param RF24NetworkHeader header: The object to save the header information to. @@ -358,7 +359,8 @@ PYBIND11_MODULE(rf24_network, m) To fetch the next available frame received by the network node, the parameter and return type is as follows: :param int maxlen: The maximum length of the message to fetch. If this parameter is unspecified or greater than - the actual frame's message size, then only the frame's full message size is used. + the actual frame's message size, then only the frame's full message size is used. Defaults to + :py:attr:`~pyrf24.rf24_network.MAX_PAYLOAD_SIZE`. :Returns: A 2-tuple containing the frame's header (of type `RF24NetworkHeader`) and the frame's message (of type `bytearray`). )docstr", diff --git a/src/pyrf24/fake_ble.py b/src/pyrf24/fake_ble.py index c9c4971..d2529dd 100644 --- a/src/pyrf24/fake_ble.py +++ b/src/pyrf24/fake_ble.py @@ -383,7 +383,9 @@ def __init__(self, radio: RF24): This attribute is exposed for debugging purposes. """ - def begin(self, ce_pin: int = None, csn_pin: int = None) -> bool: + def begin( + self, ce_pin: Optional[int] = None, csn_pin: Optional[int] = None + ) -> bool: """Initialize the radio using BLE specifications. Internally, this function also calls :meth:`~pyrf24.rf24.RF24.begin()`, so @@ -747,7 +749,7 @@ class TemperatureServiceData(ServiceData): def __init__(self): super().__init__(TEMPERATURE_UUID) - @property + @property # type: ignore[override] def data(self) -> float: """This attribute is a `float` value.""" return struct.unpack(" int: """The attribute is a 1-byte unsigned `int` value.""" return int(self._data[0]) @@ -828,7 +830,7 @@ def pa_level_at_1_meter(self, value: Union[bytes, bytearray, int]): def uuid(self) -> bytes: return self._type[:2] - @property + @property # type: ignore[override] def data(self) -> str: """This attribute is a `str` of URL data.""" value = self._data.decode() diff --git a/src/pyrf24/rf24.pyi b/src/pyrf24/rf24.pyi index 074dd1f..bd17686 100644 --- a/src/pyrf24/rf24.pyi +++ b/src/pyrf24/rf24.pyi @@ -1,5 +1,5 @@ # pylint: skip-file -from typing import Tuple, Union, overload +from typing import Tuple, Union, overload, Optional class rf24_crclength_e: RF24_CRC_DISABLED: "rf24_crclength_e" @@ -32,7 +32,9 @@ RF24_PA_MAX: rf24_pa_dbm_e = rf24_pa_dbm_e.RF24_PA_MAX class RF24: @overload - def __init__(self, ce_pin: int, csn_pin: int, spi_speed: int = 10000000) -> None: ... + def __init__( + self, ce_pin: int, csn_pin: int, spi_speed: int = 10000000 + ) -> None: ... @overload def __init__(self, spi_speed: int = 10000000) -> None: ... def available(self) -> bool: ... @@ -40,7 +42,9 @@ class RF24: @overload def begin(self) -> bool: ... @overload - def begin(self, ce_pin: int = None, csn_pin: int = None) -> bool: ... + def begin( + self, ce_pin: Optional[int] = None, csn_pin: Optional[int] = None + ) -> bool: ... def close_rx_pipe(self, pipe_number: int) -> None: ... def closeReadingPipe(self, pipe_number: int) -> None: ... def disableDynamicPayloads(self) -> None: ... @@ -62,14 +66,22 @@ class RF24: def isChipConnected(self) -> bool: ... 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 is_fifo( + self, about_tx: bool, check_empty: Optional[bool] = None + ) -> Union[bool, int]: ... + def isFifo( + self, about_tx: bool, check_empty: Optional[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, int]) -> None: ... def openWritingPipe(self, address: Union[bytes, bytearray, int]) -> None: ... - def open_rx_pipe(self, number: int, address: Union[bytes, bytearray, int]) -> None: ... - def openReadingPipe(self, number: int, address: Union[bytes, bytearray, int]) -> None: ... + def open_rx_pipe( + self, number: int, address: Union[bytes, bytearray, int] + ) -> None: ... + def openReadingPipe( + self, number: int, address: Union[bytes, bytearray, int] + ) -> None: ... def powerUp(self) -> None: ... def powerDown(self) -> None: ... def print_details(self) -> None: ... @@ -132,8 +144,12 @@ class RF24: def testRPD(self) -> bool: ... def toggle_all_pipes(self, enable: bool) -> None: ... def toggleAllPipes(self, enable: bool) -> None: ... - def tx_standby(self, timeout: int = None, start_tx: bool = True) -> bool: ... - def txStandBy(self, timeout: int = None, start_tx: bool = True) -> bool: ... + def tx_standby( + self, timeout: Optional[int] = None, start_tx: bool = True + ) -> bool: ... + def txStandBy( + self, timeout: Optional[int] = None, start_tx: bool = True + ) -> bool: ... def what_happened(self) -> Tuple[bool, bool, bool]: ... def whatHappened(self) -> Tuple[bool, bool, bool]: ... def write(self, buf: Union[bytearray, bytes], multicast: bool = False) -> bool: ... diff --git a/src/pyrf24/rf24_network.pyi b/src/pyrf24/rf24_network.pyi index b423c0e..cb914ef 100644 --- a/src/pyrf24/rf24_network.pyi +++ b/src/pyrf24/rf24_network.pyi @@ -1,9 +1,9 @@ # pylint: skip-file -from typing import Tuple, Union, List, overload +from typing import Tuple, Union, List, overload, Optional from .rf24 import RF24 MAX_USER_DEFINED_HEADER_TYPE: int = 127 -MAX_PAYLOAD_SIZE: int = 144 +MAX_PAYLOAD_SIZE: int = 1514 NETWORK_ADDR_RESPONSE: int = 128 NETWORK_PING: int = 130 EXTERNAL_DATA_TYPE: int = 131 @@ -67,7 +67,7 @@ class RF24Network: @overload def begin(self, node_address: int) -> None: ... @overload - def begin(self, channel:int, node_address: int) -> None: ... + def begin(self, channel: int, node_address: int) -> None: ... def is_address_valid(self, address: int) -> bool: ... def is_valid_address(self, address: int) -> bool: ... def multicast( @@ -79,8 +79,12 @@ class RF24Network: @overload def peek(self, header: RF24NetworkHeader) -> int: ... @overload - def peek(self, maxlen: int = None) -> Tuple[RF24NetworkHeader, bytearray]: ... - def read(self, maxlen: int = None) -> Tuple[RF24NetworkHeader, bytearray]: ... + def peek( + self, maxlen: int = MAX_PAYLOAD_SIZE + ) -> Tuple[RF24NetworkHeader, bytearray]: ... + def read( + self, maxlen: int = MAX_PAYLOAD_SIZE + ) -> Tuple[RF24NetworkHeader, bytearray]: ... def set_multicast_level(self, level: int) -> None: ... def update(self) -> int: ... def available(self) -> int: ...