diff --git a/README.rst b/README.rst index 4ede2db..1350f23 100644 --- a/README.rst +++ b/README.rst @@ -63,8 +63,8 @@ To create an Azure IoT Hub instance or an Azure IoT Central app, you will need a - If you are not a student, head to `aka.ms/FreeAz `_ and sign up to get $200 of credit for 30 days, as well as free tiers of a load of services. You will need a credit card for validation only, your card will not be charged. -ESP32SPI Networking -=================== +ESP32 AirLift Networking +======================== To use this library, you will need to create an ESP32_SPI WifiManager, connected to WiFi. You will also need to set the current time, as this is used to generate time-based authentication keys. One way to do this is via the `Adafruit CircuitPython NTP `_ library with the following code: @@ -79,7 +79,7 @@ To use this library, you will need to create an ESP32_SPI WifiManager, connected Native Networking ================= -To use this library, with boards that have native networking support, you need to be connected to a network. You will also need to set the current time, as this is used to generate time-based authentication keys. One way to do this is by using the `Adafruit IoT Time Service `_ via the `Requests library _` with the following code: +To use this library, with boards that have native networking support, you need to be connected to a network. You will also need to set the current time, as this is used to generate time-based authentication keys. One way to do this is by using the `Adafruit IoT Time API `_ via the `Adafruit Requests library `_ with the following code: .. code-block:: python diff --git a/adafruit_azureiot/__init__.py b/adafruit_azureiot/__init__.py index 1bdf383..1bfb16e 100644 --- a/adafruit_azureiot/__init__.py +++ b/adafruit_azureiot/__init__.py @@ -19,15 +19,16 @@ * Adafruit CircuitPython firmware for the supported boards: https://github.com/adafruit/circuitpython/releases -**ESP32SPI Peripheral Networking** +**With ESP32 Airlift Networking** * Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice -* Adafruit's ESP32SPI Networking library: https://github.com/adafruit/Adafruit_CircuitPython_ESP32SPI +* Adafruit's ESP32SPI library: https://github.com/adafruit/Adafruit_CircuitPython_ESP32SPI +* Adafruit's NTP library: https://github.com/adafruit/Adafruit_CircuitPython_NTP -**Native Networking** +**With Native Networking** * CircuitPython's Wifi Module: https://docs.circuitpython.org/en/latest/shared-bindings/wifi/index.html -* Adafruit's CircuitPython Requests Library: https://github.com/adafruit/Adafruit_CircuitPython_Requests/ +* Adafruit's Requests Library: https://github.com/adafruit/Adafruit_CircuitPython_Requests/ """ from .iot_error import IoTError diff --git a/adafruit_azureiot/device_registration.py b/adafruit_azureiot/device_registration.py index a59a97c..948679c 100644 --- a/adafruit_azureiot/device_registration.py +++ b/adafruit_azureiot/device_registration.py @@ -53,6 +53,7 @@ def __init__( logger: Logger = None, ): """Creates an instance of the device registration service + :param socket: The network socket :param str id_scope: The ID scope of the device to register :param str device_id: The device ID of the device to register @@ -163,6 +164,7 @@ def register_device(self, expiry: int) -> str: """ Registers the device with the IoT Central device registration service. Returns the hostname of the IoT hub to use over MQTT + :param int expiry: The expiry time for the registration :returns: The underlying IoT Hub that this device should connect to :rtype: str diff --git a/adafruit_azureiot/iot_error.py b/adafruit_azureiot/iot_error.py index 4bc5f26..dda05fe 100644 --- a/adafruit_azureiot/iot_error.py +++ b/adafruit_azureiot/iot_error.py @@ -20,6 +20,7 @@ class IoTError(Exception): def __init__(self, message: str): """Create the IoT Error + :param str message: The error message """ super().__init__(message) diff --git a/adafruit_azureiot/iot_mqtt.py b/adafruit_azureiot/iot_mqtt.py index 47fb622..10ba960 100644 --- a/adafruit_azureiot/iot_mqtt.py +++ b/adafruit_azureiot/iot_mqtt.py @@ -19,6 +19,7 @@ import adafruit_minimqtt.adafruit_minimqtt as MQTT import adafruit_logging as logging +from adafruit_logging import Logger from .iot_error import IoTError from .keys import compute_derived_symmetric_key @@ -31,6 +32,7 @@ class IoTResponse: def __init__(self, code: int, message: str): """Creates an IoT Response object + :param int code: The HTTP response code for this method call, for example 200 if the method was handled successfully :param str message: The HTTP response message for this method call """ @@ -43,17 +45,20 @@ class IoTMQTTCallback: def message_sent(self, data: str) -> None: """Called when a message is sent to the cloud + :param str data: The data send with the message """ def connection_status_change(self, connected: bool) -> None: """Called when the connection status changes + :param bool connected: True if the device is connected, otherwise false """ # pylint: disable=W0613, R0201 def direct_method_invoked(self, method_name: str, payload: str) -> IoTResponse: """Called when a direct method is invoked + :param str method_name: The name of the method that was invoked :param str payload: The payload with the message :returns: A response with a code and status to show if the method was correctly handled @@ -64,6 +69,7 @@ def direct_method_invoked(self, method_name: str, payload: str) -> IoTResponse: # pylint: disable=C0103 def cloud_to_device_message_received(self, body: str, properties: dict) -> None: """Called when a cloud to device message is received + :param str body: The body of the message :param dict properties: The propreties sent with the mesage """ @@ -72,6 +78,7 @@ def device_twin_desired_updated( self, desired_property_name: str, desired_property_value, desired_version: int ) -> None: """Called when the device twin desired properties are updated + :param str desired_property_name: The name of the desired property that was updated :param desired_property_value: The value of the desired property that was updated :param int desired_version: The version of the desired property that was updated @@ -84,6 +91,7 @@ def device_twin_reported_updated( reported_version: int, ) -> None: """Called when the device twin reported values are updated + :param str reported_property_name: The name of the reported property that was updated :param reported_property_value: The value of the reported property that was updated :param int reported_version: The version of the reported property that was updated @@ -319,9 +327,10 @@ def __init__( device_id: str, device_sas_key: str, token_expires: int = 21600, - logger: logging = None, + logger: Logger = None, ): """Create the Azure IoT MQTT client + :param IoTMQTTCallback callback: A callback class :param socket: The socket to communicate over :param iface: The network interface to communicate over @@ -329,7 +338,7 @@ def __init__( :param str device_id: The device ID of the device to register :param str device_sas_key: The primary or secondary key of the device to register :param int token_expires: The number of seconds till the token expires, defaults to 6 hours - :param adafruit_logging logger: The logger + :param Logger logger: The logger """ self._callback = callback self._socket = socket @@ -372,6 +381,7 @@ def _subscribe_to_twin_topics(self): def connect(self) -> bool: """Connects to the MQTT broker + :returns: True if the connection is successful, otherwise False :rtype: bool """ @@ -426,6 +436,7 @@ def reconnect(self) -> None: def is_connected(self) -> bool: """Gets if there is an open connection to the MQTT broker + :returns: True if there is an open connection, False if not :rtype: bool """ @@ -443,6 +454,7 @@ def send_device_to_cloud_message( self, message, system_properties: dict = None ) -> None: """Send a device to cloud message from this device to Azure IoT Hub + :param message: The message data as a JSON string or a dictionary :param system_properties: System properties to send with the message :raises: ValueError if the message is not a string or dictionary @@ -472,6 +484,7 @@ def send_device_to_cloud_message( def send_twin_patch(self, patch) -> None: """Send a patch for the reported properties of the device twin + :param patch: The patch as a JSON string or a dictionary :raises: IoTError if the data is not a string or dictionary :raises RuntimeError: if the internet connection is not responding or is unable to connect diff --git a/adafruit_azureiot/iotcentral_device.py b/adafruit_azureiot/iotcentral_device.py index 96e0180..53fbf51 100644 --- a/adafruit_azureiot/iotcentral_device.py +++ b/adafruit_azureiot/iotcentral_device.py @@ -15,6 +15,7 @@ import json import time import adafruit_logging as logging +from adafruit_logging import Logger from .device_registration import DeviceRegistration from .iot_error import IoTError from .iot_mqtt import IoTMQTT, IoTMQTTCallback, IoTResponse @@ -25,6 +26,7 @@ class IoTCentralDevice(IoTMQTTCallback): def connection_status_change(self, connected: bool) -> None: """Called when the connection status changes + :param bool connected: True if the device is connected, otherwise false """ if self.on_connection_status_changed is not None: @@ -34,6 +36,7 @@ def connection_status_change(self, connected: bool) -> None: # pylint: disable=W0613, R0201 def direct_method_called(self, method_name: str, payload: str) -> IoTResponse: """Called when a direct method is invoked + :param str method_name: The name of the method that was invoked :param str payload: The payload with the message :returns: A response with a code and status to show if the method was correctly handled @@ -49,6 +52,7 @@ def device_twin_desired_updated( self, desired_property_name: str, desired_property_value, desired_version: int ) -> None: """Called when the device twin desired properties are updated + :param str desired_property_name: The name of the desired property that was updated :param desired_property_value: The value of the desired property that was updated :param int desired_version: The version of the desired property that was updated @@ -69,6 +73,7 @@ def device_twin_reported_updated( reported_version: int, ) -> None: """Called when the device twin reported values are updated + :param str reported_property_name: The name of the reported property that was updated :param reported_property_value: The value of the reported property that was updated :param int reported_version: The version of the reported property that was updated @@ -88,16 +93,17 @@ def __init__( device_id: str, device_sas_key: str, token_expires: int = 21600, - logger: logging = None, + logger: Logger = None, ): """Create the Azure IoT Central device client + :param socket: The network socket :param iface: The network interface :param str id_scope: The ID Scope of the device in IoT Central :param str device_id: The device ID of the device in IoT Central :param str device_sas_key: The primary or secondary key of the device in IoT Central :param int token_expires: The number of seconds till the token expires, defaults to 6 hours - :param adafruit_logging logger: The logger + :param Logger logger: The logger """ self._socket = socket self._iface = iface @@ -132,6 +138,7 @@ def property_changed(_property_name: str, property_value, version: int) -> None def connect(self) -> None: """Connects to Azure IoT Central + :raises DeviceRegistrationError: if the device cannot be registered successfully :raises RuntimeError: if the internet connection is not responding or is unable to connect """ @@ -166,6 +173,7 @@ def connect(self) -> None: def disconnect(self) -> None: """Disconnects from the MQTT broker + :raises IoTError: if there is no open connection to the MQTT broker """ if self._mqtt is None: @@ -182,6 +190,7 @@ def reconnect(self) -> None: def is_connected(self) -> bool: """Gets if there is an open connection to the MQTT broker + :returns: True if there is an open connection, False if not :rtype: bool """ @@ -189,6 +198,7 @@ def is_connected(self) -> bool: def loop(self) -> None: """Listens for MQTT messages + :raises IoTError: if there is no open connection to the MQTT broker """ if self._mqtt is None: @@ -198,6 +208,7 @@ def loop(self) -> None: def send_property(self, property_name: str, value) -> None: """Updates the value of a writable property + :param str property_name: The name of the property to write to :param value: The value to set on the property :raises IoTError: if there is no open connection to the MQTT broker @@ -211,6 +222,7 @@ def send_property(self, property_name: str, value) -> None: def send_telemetry(self, data) -> None: """Sends telemetry to the IoT Central app + :param data: The telemetry data to send :raises IoTError: if there is no open connection to the MQTT broker """ diff --git a/adafruit_azureiot/iothub_device.py b/adafruit_azureiot/iothub_device.py index 06288e2..e4f0410 100755 --- a/adafruit_azureiot/iothub_device.py +++ b/adafruit_azureiot/iothub_device.py @@ -19,6 +19,7 @@ import json import adafruit_logging as logging +from adafruit_logging import Logger from .iot_error import IoTError from .iot_mqtt import IoTMQTT, IoTMQTTCallback, IoTResponse @@ -65,6 +66,7 @@ class IoTHubDevice(IoTMQTTCallback): def connection_status_change(self, connected: bool) -> None: """Called when the connection status changes + :param bool connected: True if the device is connected, otherwise false """ if self._on_connection_status_changed is not None: @@ -74,6 +76,7 @@ def connection_status_change(self, connected: bool) -> None: # pylint: disable=W0613, R0201 def direct_method_invoked(self, method_name: str, payload: str) -> IoTResponse: """Called when a direct method is invoked + :param str method_name: The name of the method that was invoked :param str payload: The payload with the message :returns: A response with a code and status to show if the method was correctly handled @@ -88,6 +91,7 @@ def direct_method_invoked(self, method_name: str, payload: str) -> IoTResponse: # pylint: disable=C0103 def cloud_to_device_message_received(self, body: str, properties: dict) -> None: """Called when a cloud to device message is received + :param str body: The body of the message :param dict properties: The propreties sent with the mesage """ @@ -102,6 +106,7 @@ def device_twin_desired_updated( desired_version: int, ) -> None: """Called when the device twin desired properties are updated + :param str desired_property_name: The name of the desired property that was updated :param desired_property_value: The value of the desired property that was updated :param int desired_version: The version of the desired property that was updated @@ -119,6 +124,7 @@ def device_twin_reported_updated( reported_version: int, ) -> None: """Called when the device twin reported values are updated + :param str reported_property_name: The name of the reported property that was updated :param reported_property_value: The value of the reported property that was updated :param int reported_version: The version of the reported property that was updated @@ -135,14 +141,15 @@ def __init__( iface, device_connection_string: str, token_expires: int = 21600, - logger: logging = None, + logger: Logger = None, ): """Create the Azure IoT Central device client + :param socket: The network socket :param iface: The network interface :param str device_connection_string: The Iot Hub device connection string :param int token_expires: The number of seconds till the token expires, defaults to 6 hours - :param adafruit_logging logger: The logger + :param Logger logger: The logger """ self._socket = socket self._iface = iface @@ -286,6 +293,7 @@ def device_twin_reported_updated(reported_property_name: str, reported_property_ def connect(self) -> None: """Connects to Azure IoT Hub + :raises RuntimeError: if the internet connection is not responding or is unable to connect """ self._mqtt = IoTMQTT( @@ -308,6 +316,7 @@ def connect(self) -> None: def loop(self) -> None: """Listens for MQTT messages + :raises IoTError: if there is no open connection to the MQTT broker """ if self._mqtt is None: @@ -317,6 +326,7 @@ def loop(self) -> None: def disconnect(self) -> None: """Disconnects from the MQTT broker + :raises IoTError: if there is no open connection to the MQTT broker """ if self._mqtt is None: @@ -333,6 +343,7 @@ def reconnect(self) -> None: def is_connected(self) -> bool: """Gets if there is an open connection to the MQTT broker + :returns: True if there is an open connection, False if not :rtype: bool """ @@ -342,6 +353,7 @@ def send_device_to_cloud_message( self, message: Union[str, dict], system_properties: dict = None ) -> None: """Send a device to cloud message from this device to Azure IoT Hub + :param message: The message data as a JSON string or a dictionary :param system_properties: System properties to send with the message :raises: ValueError if the message is not a string or dictionary @@ -354,6 +366,7 @@ def send_device_to_cloud_message( def update_twin(self, patch: Union[str, dict]) -> None: """Updates the reported properties in the devices device twin + :param patch: The JSON patch to apply to the device twin reported properties """ if self._mqtt is None: diff --git a/adafruit_azureiot/keys.py b/adafruit_azureiot/keys.py index 83d7250..107accb 100644 --- a/adafruit_azureiot/keys.py +++ b/adafruit_azureiot/keys.py @@ -3,6 +3,7 @@ # SPDX-License-Identifier: MIT """Computes a derived symmetric key from a secret and a message + :param str secret: The secret to use for the key :param str msg: The message to use for the key :returns: The derived symmetric key @@ -15,6 +16,7 @@ def compute_derived_symmetric_key(secret: str, msg: str) -> bytes: """Computes a derived symmetric key from a secret and a message + :param str secret: The secret to use for the key :param str msg: The message to use for the key :returns: The derived symmetric key diff --git a/docs/examples.rst b/docs/examples.rst index 73d42b2..6ea5ea0 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -1,5 +1,5 @@ -IoT Hub ESP32SPI Networking ------------- +IoT Hub ESP32 AirLift Networking +-------------------------------- Ensure your IoT Hub device works with this simple test. @@ -25,8 +25,8 @@ Update the reported properties of the devices device twin, and receive updates t :caption: examples/esp32spi/azureiot_hub_twin_operations.py :linenos: -IoT Central ESP32SPI Networking ------------- +IoT Central ESP32 AirLift Networking +------------------------------------ Ensure your IoT Central device works with this simple test. @@ -53,7 +53,7 @@ Handle connection errors. :linenos: IoT Hub Native Networking ------------- +------------------------- Ensure your IoT Hub device works with this simple test. @@ -80,7 +80,7 @@ Update the reported properties of the devices device twin, and receive updates t :linenos: IoT Central Native Networking ------------- +----------------------------- Ensure your IoT Central device works with this simple test. diff --git a/docs/requirements.txt b/docs/requirements.txt index 88e6733..dcea916 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,4 +2,4 @@ # # SPDX-License-Identifier: Unlicense -sphinx>=4.0.0 +sphinx diff --git a/examples/ esp32spi /azureiot_central_commands.py b/examples/esp32spi/azureiot_central_commands.py similarity index 100% rename from examples/ esp32spi /azureiot_central_commands.py rename to examples/esp32spi/azureiot_central_commands.py diff --git a/examples/ esp32spi /azureiot_central_notconnected.py b/examples/esp32spi/azureiot_central_notconnected.py similarity index 100% rename from examples/ esp32spi /azureiot_central_notconnected.py rename to examples/esp32spi/azureiot_central_notconnected.py diff --git a/examples/ esp32spi /azureiot_central_properties.py b/examples/esp32spi/azureiot_central_properties.py similarity index 100% rename from examples/ esp32spi /azureiot_central_properties.py rename to examples/esp32spi/azureiot_central_properties.py diff --git a/examples/ esp32spi /azureiot_central_simpletest.py b/examples/esp32spi/azureiot_central_simpletest.py similarity index 100% rename from examples/ esp32spi /azureiot_central_simpletest.py rename to examples/esp32spi/azureiot_central_simpletest.py diff --git a/examples/ esp32spi /azureiot_hub_directmethods.py b/examples/esp32spi/azureiot_hub_directmethods.py similarity index 100% rename from examples/ esp32spi /azureiot_hub_directmethods.py rename to examples/esp32spi/azureiot_hub_directmethods.py diff --git a/examples/ esp32spi /azureiot_hub_messages.py b/examples/esp32spi/azureiot_hub_messages.py similarity index 100% rename from examples/ esp32spi /azureiot_hub_messages.py rename to examples/esp32spi/azureiot_hub_messages.py diff --git a/examples/ esp32spi /azureiot_hub_simpletest.py b/examples/esp32spi/azureiot_hub_simpletest.py similarity index 100% rename from examples/ esp32spi /azureiot_hub_simpletest.py rename to examples/esp32spi/azureiot_hub_simpletest.py diff --git a/examples/ esp32spi /azureiot_hub_twin_operations.py b/examples/esp32spi/azureiot_hub_twin_operations.py similarity index 100% rename from examples/ esp32spi /azureiot_hub_twin_operations.py rename to examples/esp32spi/azureiot_hub_twin_operations.py diff --git a/examples/native_networking/azureiot_hub_simpletest.py b/examples/native_networking/azureiot_hub_simpletest.py index 57dc741..8dad80b 100644 --- a/examples/native_networking/azureiot_hub_simpletest.py +++ b/examples/native_networking/azureiot_hub_simpletest.py @@ -71,7 +71,6 @@ pool = socketpool.SocketPool(wifi.radio) # Create an IoT Hub device client and connect device = IoTHubDevice(pool, esp, secrets["device_connection_string"]) -print(dir(device)) print("Connecting to Azure IoT Hub...") diff --git a/requirements.txt b/requirements.txt index 5e8305a..6c0c201 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,5 +4,4 @@ Adafruit-Blinka Adafruit-CircuitPython-miniMQTT -Adafruit-CircuitPython-Requests Adafruit-CircuitPython-Binascii