From 4050fa5b856ff75e144e71a78103c94c92f1765b Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 19 May 2020 15:20:50 -0400 Subject: [PATCH 1/4] update for MMQTT --- adafruit_azureiot/device_registration.py | 45 ++++++++-- adafruit_azureiot/iot_mqtt.py | 110 +++++++++++++++++------ adafruit_azureiot/iotcentral_device.py | 45 ++++++++-- adafruit_azureiot/iothub_device.py | 62 ++++++++++--- docs/conf.py | 25 +++++- examples/iotcentral_commands.py | 8 +- examples/iotcentral_notconnected.py | 8 +- examples/iotcentral_properties.py | 17 +++- examples/iotcentral_simpletest.py | 8 +- examples/iothub_directmethods.py | 4 +- examples/iothub_messages.py | 4 +- examples/iothub_simpletest.py | 4 +- examples/iothub_twin_operations.py | 17 +++- 13 files changed, 284 insertions(+), 73 deletions(-) diff --git a/adafruit_azureiot/device_registration.py b/adafruit_azureiot/device_registration.py index dc83ab3..a0f6063 100644 --- a/adafruit_azureiot/device_registration.py +++ b/adafruit_azureiot/device_registration.py @@ -72,9 +72,13 @@ def _parse_http_status(status_code: int, status_reason: str) -> None: """ for error in AZURE_HTTP_ERROR_CODES: if error == status_code: - raise DeviceRegistrationError("Error {0}: {1}".format(status_code, status_reason)) + raise DeviceRegistrationError( + "Error {0}: {1}".format(status_code, status_reason) + ) - def __init__(self, socket, id_scope: str, device_id: str, key: str, logger: Logger = None): + def __init__( + self, socket, id_scope: str, device_id: str, key: str, 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 @@ -98,7 +102,9 @@ def compute_derived_symmetric_key(secret: str, msg: str) -> bytes: :rtype: bytes """ secret = base64.b64decode(secret) - return base64.b64encode(hmac.new(secret, msg=msg.encode("utf8"), digestmod=hashlib.sha256).digest()) + return base64.b64encode( + hmac.new(secret, msg=msg.encode("utf8"), digestmod=hashlib.sha256).digest() + ) def _loop_assign(self, operation_id, headers) -> str: uri = "https://%s/%s/registrations/%s/operations/%s?api-version=%s" % ( @@ -155,7 +161,10 @@ def _run_put_request_with_retry(self, url, body, headers): self._logger.debug("Sent!") break except RuntimeError as runtime_error: - self._logger.info("Could not send data, retrying after 0.5 seconds: " + str(runtime_error)) + self._logger.info( + "Could not send data, retrying after 0.5 seconds: " + + str(runtime_error) + ) retry = retry + 1 if retry >= 10: @@ -180,7 +189,10 @@ def _run_get_request_with_retry(self, url, headers): self._logger.debug("Sent!") break except RuntimeError as runtime_error: - self._logger.info("Could not send data, retrying after 0.5 seconds: " + str(runtime_error)) + self._logger.info( + "Could not send data, retrying after 0.5 seconds: " + + str(runtime_error) + ) retry = retry + 1 if retry >= 10: @@ -205,9 +217,19 @@ def register_device(self, expiry: int) -> str: """ # pylint: disable=C0103 sr = self._id_scope + "%2Fregistrations%2F" + self._device_id - sig_no_encode = DeviceRegistration.compute_derived_symmetric_key(self._key, sr + "\n" + str(expiry)) + sig_no_encode = DeviceRegistration.compute_derived_symmetric_key( + self._key, sr + "\n" + str(expiry) + ) sig_encoded = parse.quote(sig_no_encode, "~()*!.'") - auth_string = "SharedAccessSignature sr=" + sr + "&sig=" + sig_encoded + "&se=" + str(expiry) + "&skn=registration" + auth_string = ( + "SharedAccessSignature sr=" + + sr + + "&sig=" + + sig_encoded + + "&se=" + + str(expiry) + + "&skn=registration" + ) headers = { "content-type": "application/json; charset=utf-8", @@ -238,7 +260,14 @@ def register_device(self, expiry: int) -> str: try: data = response.json() except ValueError as error: - err = "ERROR: non JSON is received from " + constants.DPS_END_POINT + " => " + str(response) + " .. message : " + str(error) + err = ( + "ERROR: non JSON is received from " + + constants.DPS_END_POINT + + " => " + + str(response) + + " .. message : " + + str(error) + ) self._logger.error(err) raise DeviceRegistrationError(err) diff --git a/adafruit_azureiot/iot_mqtt.py b/adafruit_azureiot/iot_mqtt.py index 62537cb..698cd35 100644 --- a/adafruit_azureiot/iot_mqtt.py +++ b/adafruit_azureiot/iot_mqtt.py @@ -84,14 +84,21 @@ def cloud_to_device_message_received(self, body: str, properties: dict) -> None: :param dict properties: The propreties sent with the mesage """ - def device_twin_desired_updated(self, desired_property_name: str, desired_property_value, desired_version: int) -> None: + 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 """ - def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, reported_version: int) -> None: + def device_twin_reported_updated( + self, + reported_property_name: str, + reported_property_value, + 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 @@ -107,11 +114,17 @@ class IoTMQTT: def _gen_sas_token(self) -> str: token_expiry = int(time.time() + self._token_expires) uri = self._hostname + "%2Fdevices%2F" + self._device_id - signed_hmac_sha256 = DeviceRegistration.compute_derived_symmetric_key(self._key, uri + "\n" + str(token_expiry)) + signed_hmac_sha256 = DeviceRegistration.compute_derived_symmetric_key( + self._key, uri + "\n" + str(token_expiry) + ) signature = parse.quote(signed_hmac_sha256, "~()*!.'") - if signature.endswith("\n"): # somewhere along the crypto chain a newline is inserted + if signature.endswith( + "\n" + ): # somewhere along the crypto chain a newline is inserted signature = signature[:-1] - token = "SharedAccessSignature sr={}&sig={}&se={}".format(uri, signature, token_expiry) + token = "SharedAccessSignature sr={}&sig={}&se={}".format( + uri, signature, token_expiry + ) return token # Workaround for https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/issues/25 @@ -143,15 +156,16 @@ def _try_create_mqtt_client(self, hostname: str) -> None: self._mqtts.connect() def _create_mqtt_client(self) -> None: - try: - self._try_create_mqtt_client(self._hostname) - except ValueError: - # Workaround for https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/issues/25 - self._try_create_mqtt_client("https://" + self._hostname) + self._try_create_mqtt_client(self._hostname) # pylint: disable=C0103, W0613 def _on_connect(self, client, userdata, _, rc) -> None: - self._logger.info("- iot_mqtt :: _on_connect :: rc = " + str(rc) + ", userdata = " + str(userdata)) + self._logger.info( + "- iot_mqtt :: _on_connect :: rc = " + + str(rc) + + ", userdata = " + + str(userdata) + ) if rc == 0: self._mqtt_connected = True self._auth_response_received = True @@ -178,7 +192,9 @@ def _on_disconnect(self, client, userdata, rc) -> None: self._callback.connection_status_change(False) def _on_publish(self, client, data, topic, msg_id) -> None: - self._logger.info("- iot_mqtt :: _on_publish :: " + str(data) + " on topic " + str(topic)) + self._logger.info( + "- iot_mqtt :: _on_publish :: " + str(data) + " on topic " + str(topic) + ) # pylint: disable=W0703 def _handle_device_twin_update(self, msg: str, topic: str) -> None: @@ -189,7 +205,12 @@ def _handle_device_twin_update(self, msg: str, topic: str) -> None: try: twin = json.loads(msg) except json.JSONDecodeError as e: - self._logger.error("ERROR: JSON parse for Device Twin message object has failed. => " + msg + " => " + str(e)) + self._logger.error( + "ERROR: JSON parse for Device Twin message object has failed. => " + + msg + + " => " + + str(e) + ) return if "reported" in twin: @@ -199,11 +220,15 @@ def _handle_device_twin_update(self, msg: str, topic: str) -> None: reported_version = reported["$version"] reported.pop("$version") else: - self._logger.error("ERROR: Unexpected payload for reported twin update => " + msg) + self._logger.error( + "ERROR: Unexpected payload for reported twin update => " + msg + ) return for property_name, value in reported.items(): - self._callback.device_twin_reported_updated(property_name, value, reported_version) + self._callback.device_twin_reported_updated( + property_name, value, reported_version + ) is_patch = "desired" not in twin @@ -216,11 +241,15 @@ def _handle_device_twin_update(self, msg: str, topic: str) -> None: desired_version = desired["$version"] desired.pop("$version") else: - self._logger.error("ERROR: Unexpected payload for desired twin update => " + msg) + self._logger.error( + "ERROR: Unexpected payload for desired twin update => " + msg + ) return for property_name, value in desired.items(): - self._callback.device_twin_desired_updated(property_name, value, desired_version) + self._callback.device_twin_desired_updated( + property_name, value, desired_version + ) def _handle_direct_method(self, msg: str, topic: str) -> None: index = topic.find("$rid=") @@ -249,7 +278,14 @@ def _handle_direct_method(self, msg: str, topic: str) -> None: ret_message = json.dumps(ret_json) next_topic = "$iothub/methods/res/{}/?$rid={}".format(ret_code, method_id) - self._logger.info("C2D: => " + next_topic + " with data " + ret_message + " and name => " + method_name) + self._logger.info( + "C2D: => " + + next_topic + + " with data " + + ret_message + + " and name => " + + method_name + ) self._send_common(next_topic, ret_message) def _handle_cloud_to_device_message(self, msg: str, topic: str) -> None: @@ -282,14 +318,18 @@ def _on_message(self, client, msg_topic, payload) -> None: topic = str(msg_topic) if topic.startswith("$iothub/"): - if topic.startswith("$iothub/twin/PATCH/properties/desired/") or topic.startswith("$iothub/twin/res/200/?$rid="): + if topic.startswith( + "$iothub/twin/PATCH/properties/desired/" + ) or topic.startswith("$iothub/twin/res/200/?$rid="): self._handle_device_twin_update(str(msg), topic) elif topic.startswith("$iothub/methods"): self._handle_direct_method(str(msg), topic) else: if not topic.startswith("$iothub/twin/res/"): # not twin response self._logger.error("ERROR: unknown twin! - {}".format(msg)) - elif topic.startswith("devices/{}/messages/devicebound".format(self._device_id)): + elif topic.startswith( + "devices/{}/messages/devicebound".format(self._device_id) + ): self._handle_cloud_to_device_message(str(msg), topic) else: self._logger.error("ERROR: (unknown message) - {}".format(msg)) @@ -315,7 +355,10 @@ def _send_common(self, topic: str, data) -> None: self._logger.debug("Data sent") break except RuntimeError as runtime_error: - self._logger.info("Could not send data, retrying after 0.5 seconds: " + str(runtime_error)) + self._logger.info( + "Could not send data, retrying after 0.5 seconds: " + + str(runtime_error) + ) retry = retry + 1 if retry >= 10: @@ -364,18 +407,24 @@ def __init__( self._hostname = hostname self._key = key self._token_expires = token_expires - self._username = "{}/{}/api-version={}".format(self._hostname, device_id, constants.IOTC_API_VERSION) + self._username = "{}/{}/api-version={}".format( + self._hostname, device_id, constants.IOTC_API_VERSION + ) self._passwd = self._gen_sas_token() self._logger = logger if logger is not None else logging.getLogger("log") self._is_subscribed_to_twins = False def _subscribe_to_core_topics(self): self._mqtts.subscribe("devices/{}/messages/events/#".format(self._device_id)) - self._mqtts.subscribe("devices/{}/messages/devicebound/#".format(self._device_id)) + self._mqtts.subscribe( + "devices/{}/messages/devicebound/#".format(self._device_id) + ) self._mqtts.subscribe("$iothub/methods/#") def _subscribe_to_twin_topics(self): - self._mqtts.subscribe("$iothub/twin/PATCH/properties/desired/#") # twin desired property changes + self._mqtts.subscribe( + "$iothub/twin/PATCH/properties/desired/#" + ) # twin desired property changes self._mqtts.subscribe("$iothub/twin/res/#") # twin properties response def connect(self) -> bool: @@ -391,7 +440,10 @@ def connect(self) -> bool: while self._auth_response_received is None: self.loop() - self._logger.info(" - iot_mqtt :: connect :: on_connect must be fired. Connected ? " + str(self.is_connected())) + self._logger.info( + " - iot_mqtt :: connect :: on_connect must be fired. Connected ? " + + str(self.is_connected()) + ) if not self.is_connected(): return False @@ -448,7 +500,9 @@ def loop(self) -> None: self._mqtts.loop() - def send_device_to_cloud_message(self, message, system_properties: dict = None) -> None: + 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 @@ -484,5 +538,7 @@ def send_twin_patch(self, patch) -> None: :raises RuntimeError: if the internet connection is not responding or is unable to connect """ self._logger.info("- iot_mqtt :: sendProperty :: " + str(patch)) - topic = "$iothub/twin/PATCH/properties/reported/?$rid={}".format(int(time.time())) + topic = "$iothub/twin/PATCH/properties/reported/?$rid={}".format( + int(time.time()) + ) self._send_common(topic, patch) diff --git a/adafruit_azureiot/iotcentral_device.py b/adafruit_azureiot/iotcentral_device.py index 43270cc..23fe9d1 100644 --- a/adafruit_azureiot/iotcentral_device.py +++ b/adafruit_azureiot/iotcentral_device.py @@ -62,7 +62,9 @@ def direct_method_called(self, method_name: str, payload: str) -> IoTResponse: raise IoTError("on_command_executed not set") - def device_twin_desired_updated(self, desired_property_name: str, desired_property_value, desired_version: int) -> None: + 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 @@ -70,12 +72,19 @@ def device_twin_desired_updated(self, desired_property_name: str, desired_proper """ if self.on_property_changed is not None: # pylint: disable=E1102 - self.on_property_changed(desired_property_name, desired_property_value, desired_version) + self.on_property_changed( + desired_property_name, desired_property_value, desired_version + ) # when a desired property changes, update the reported to match to keep them in sync self.send_property(desired_property_name, desired_property_value) - def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, reported_version: int) -> None: + def device_twin_reported_updated( + self, + reported_property_name: str, + reported_property_value, + 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 @@ -83,10 +92,21 @@ def device_twin_reported_updated(self, reported_property_name: str, reported_pro """ if self.on_property_changed is not None: # pylint: disable=E1102 - self.on_property_changed(reported_property_name, reported_property_value, reported_version) + self.on_property_changed( + reported_property_name, reported_property_value, reported_version + ) # pylint: disable=R0913 - def __init__(self, socket, iface, id_scope: str, device_id: str, key: str, token_expires: int = 21600, logger: logging = None): + def __init__( + self, + socket, + iface, + id_scope: str, + device_id: str, + key: str, + token_expires: int = 21600, + logger: logging = None, + ): """Create the Azure IoT Central device client :param socket: The network socket :param iface: The network interface @@ -132,11 +152,22 @@ def connect(self) -> None: :raises DeviceRegistrationError: if the device cannot be registered successfully :raises RuntimeError: if the internet connection is not responding or is unable to connect """ - self._device_registration = DeviceRegistration(self._socket, self._id_scope, self._device_id, self._key, self._logger) + self._device_registration = DeviceRegistration( + self._socket, self._id_scope, self._device_id, self._key, self._logger + ) token_expiry = int(time.time() + self._token_expires) hostname = self._device_registration.register_device(token_expiry) - self._mqtt = IoTMQTT(self, self._socket, self._iface, hostname, self._device_id, self._key, self._token_expires, self._logger) + self._mqtt = IoTMQTT( + self, + self._socket, + self._iface, + hostname, + self._device_id, + self._key, + self._token_expires, + self._logger, + ) self._mqtt.connect() self._mqtt.subscribe_to_twins() diff --git a/adafruit_azureiot/iothub_device.py b/adafruit_azureiot/iothub_device.py index c7900d6..6ccaf79 100755 --- a/adafruit_azureiot/iothub_device.py +++ b/adafruit_azureiot/iothub_device.py @@ -108,7 +108,9 @@ def cloud_to_device_message_received(self, body: str, properties: dict) -> None: # pylint: disable=E1102 self._on_cloud_to_device_message_received(body, properties) - def device_twin_desired_updated(self, desired_property_name: str, desired_property_value, desired_version: int) -> None: + 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 @@ -116,9 +118,16 @@ def device_twin_desired_updated(self, desired_property_name: str, desired_proper """ if self._on_device_twin_desired_updated is not None: # pylint: disable=E1102 - self._on_device_twin_desired_updated(desired_property_name, desired_property_value, desired_version) - - def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, reported_version: int) -> None: + self._on_device_twin_desired_updated( + desired_property_name, desired_property_value, desired_version + ) + + def device_twin_reported_updated( + self, + reported_property_name: str, + reported_property_value, + 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 @@ -126,9 +135,18 @@ def device_twin_reported_updated(self, reported_property_name: str, reported_pro """ if self._on_device_twin_reported_updated is not None: # pylint: disable=E1102 - self._on_device_twin_reported_updated(reported_property_name, reported_property_value, reported_version) - - def __init__(self, socket, iface, device_connection_string: str, token_expires: int = 21600, logger: logging = None): + self._on_device_twin_reported_updated( + reported_property_name, reported_property_value, reported_version + ) + + def __init__( + self, + socket, + iface, + device_connection_string: str, + token_expires: int = 21600, + logger: logging = None, + ): """Create the Azure IoT Central device client :param socket: The network socket :param iface: The network interface @@ -145,9 +163,13 @@ def __init__(self, socket, iface, device_connection_string: str, token_expires: try: cs_args = device_connection_string.split(DELIMITER) - connection_string_values = dict(arg.split(VALUE_SEPARATOR, 1) for arg in cs_args) + connection_string_values = dict( + arg.split(VALUE_SEPARATOR, 1) for arg in cs_args + ) except (ValueError, AttributeError): - raise ValueError("Connection string is required and should not be empty or blank and must be supplied as a string") + raise ValueError( + "Connection string is required and should not be empty or blank and must be supplied as a string" + ) if len(cs_args) != len(connection_string_values): raise ValueError("Invalid Connection String - Unable to parse") @@ -218,11 +240,15 @@ def cloud_to_device_message_received(body: str, properties: dict) -> None: return self._on_cloud_to_device_message_received @on_cloud_to_device_message_received.setter - def on_cloud_to_device_message_received(self, new_on_cloud_to_device_message_received): + def on_cloud_to_device_message_received( + self, new_on_cloud_to_device_message_received + ): """A callback method that is called when a cloud to device message is received. This method should have the following signature: def cloud_to_device_message_received(body: str, properties: dict) -> None: """ - self._on_cloud_to_device_message_received = new_on_cloud_to_device_message_received + self._on_cloud_to_device_message_received = ( + new_on_cloud_to_device_message_received + ) @property def on_device_twin_desired_updated(self): @@ -267,11 +293,21 @@ def connect(self) -> None: :raises RuntimeError: if the internet connection is not responding or is unable to connect """ self._mqtt = IoTMQTT( - self, self._socket, self._iface, self._hostname, self._device_id, self._shared_access_key, self._token_expires, self._logger + self, + self._socket, + self._iface, + self._hostname, + self._device_id, + self._shared_access_key, + self._token_expires, + self._logger, ) self._mqtt.connect() - if self._on_device_twin_desired_updated is not None or self._on_device_twin_reported_updated is not None: + if ( + self._on_device_twin_desired_updated is not None + or self._on_device_twin_reported_updated is not None + ): self._mqtt.subscribe_to_twins() def disconnect(self) -> None: diff --git a/docs/conf.py b/docs/conf.py index 41677b7..45a7416 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,7 +21,12 @@ # Uncomment the below if you use native CircuitPython modules such as # digitalio, micropython and busio. List the modules you use. Without it, the # autodoc module docs will fail to generate with a warning. -autodoc_mock_imports = ["adafruit_logging", "adafruit_requests", "adafruit_hashlib", "adafruit_ntp"] +autodoc_mock_imports = [ + "adafruit_logging", + "adafruit_requests", + "adafruit_hashlib", + "adafruit_ntp", +] intersphinx_mapping = { @@ -137,14 +142,28 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, "AdafruitAzureIoTLibrary.tex", "AdafruitAzureIoT Library Documentation", author, "manual",), + ( + master_doc, + "AdafruitAzureIoTLibrary.tex", + "AdafruitAzureIoT Library Documentation", + author, + "manual", + ), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [(master_doc, "AdafruitAzureIoTlibrary", "Adafruit AzureIoT Library Documentation", [author], 1,)] +man_pages = [ + ( + master_doc, + "AdafruitAzureIoTlibrary", + "Adafruit AzureIoT Library Documentation", + [author], + 1, + ) +] # -- Options for Texinfo output ------------------------------------------- diff --git a/examples/iotcentral_commands.py b/examples/iotcentral_commands.py index e8c3a56..a61d054 100644 --- a/examples/iotcentral_commands.py +++ b/examples/iotcentral_commands.py @@ -28,7 +28,9 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards +status_light = neopixel.NeoPixel( + board.NEOPIXEL, 1, brightness=0.2 +) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -94,7 +96,9 @@ from adafruit_azureiot.iot_mqtt import IoTResponse # Create an IoT Hub device client and connect -device = IoTCentralDevice(socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"]) +device = IoTCentralDevice( + socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"] +) # Subscribe to commands # Commands can be sent from the devices Dashboard in IoT Central, assuming diff --git a/examples/iotcentral_notconnected.py b/examples/iotcentral_notconnected.py index 4a9f4d6..d1a8289 100644 --- a/examples/iotcentral_notconnected.py +++ b/examples/iotcentral_notconnected.py @@ -30,7 +30,9 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards +status_light = neopixel.NeoPixel( + board.NEOPIXEL, 1, brightness=0.2 +) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -95,7 +97,9 @@ from adafruit_azureiot import IoTCentralDevice, IoTError # Create an IoT Hub device client and connect -device = IoTCentralDevice(socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"]) +device = IoTCentralDevice( + socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"] +) # don't connect # device.connect() diff --git a/examples/iotcentral_properties.py b/examples/iotcentral_properties.py index 15dde99..d251a20 100644 --- a/examples/iotcentral_properties.py +++ b/examples/iotcentral_properties.py @@ -29,7 +29,9 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards +status_light = neopixel.NeoPixel( + board.NEOPIXEL, 1, brightness=0.2 +) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -94,13 +96,22 @@ from adafruit_azureiot import IoTCentralDevice # Create an IoT Hub device client and connect -device = IoTCentralDevice(socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"]) +device = IoTCentralDevice( + socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"] +) # Subscribe to property changes # Properties can be updated either in code, or by adding a form to the view # in the device template, and setting the value on the dashboard for the device def property_changed(property_name, property_value, version): - print("Property", property_name, "updated to", str(property_value), "version", str(version)) + print( + "Property", + property_name, + "updated to", + str(property_value), + "version", + str(version), + ) # Subscribe to the property changed event diff --git a/examples/iotcentral_simpletest.py b/examples/iotcentral_simpletest.py index 571ee38..ba9e328 100644 --- a/examples/iotcentral_simpletest.py +++ b/examples/iotcentral_simpletest.py @@ -30,7 +30,9 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards +status_light = neopixel.NeoPixel( + board.NEOPIXEL, 1, brightness=0.2 +) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -95,7 +97,9 @@ from adafruit_azureiot import IoTCentralDevice # Create an IoT Hub device client and connect -device = IoTCentralDevice(socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"]) +device = IoTCentralDevice( + socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"] +) print("Connecting to Azure IoT Central...") diff --git a/examples/iothub_directmethods.py b/examples/iothub_directmethods.py index 341a51f..9153349 100644 --- a/examples/iothub_directmethods.py +++ b/examples/iothub_directmethods.py @@ -28,7 +28,9 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards +status_light = neopixel.NeoPixel( + board.NEOPIXEL, 1, brightness=0.2 +) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED diff --git a/examples/iothub_messages.py b/examples/iothub_messages.py index 52524b1..7b6f517 100644 --- a/examples/iothub_messages.py +++ b/examples/iothub_messages.py @@ -30,7 +30,9 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards +status_light = neopixel.NeoPixel( + board.NEOPIXEL, 1, brightness=0.2 +) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED diff --git a/examples/iothub_simpletest.py b/examples/iothub_simpletest.py index 703190c..aba2da4 100644 --- a/examples/iothub_simpletest.py +++ b/examples/iothub_simpletest.py @@ -30,7 +30,9 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards +status_light = neopixel.NeoPixel( + board.NEOPIXEL, 1, brightness=0.2 +) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED diff --git a/examples/iothub_twin_operations.py b/examples/iothub_twin_operations.py index 83ef88b..9942c5a 100644 --- a/examples/iothub_twin_operations.py +++ b/examples/iothub_twin_operations.py @@ -29,7 +29,9 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards +status_light = neopixel.NeoPixel( + board.NEOPIXEL, 1, brightness=0.2 +) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -98,8 +100,17 @@ # To see these changes, update the desired properties for the device either in code # or in the Azure portal by selecting the device in the IoT Hub blade, selecting # Device Twin then adding or amending an entry in the 'desired' section -def device_twin_desired_updated(desired_property_name: str, desired_property_value, desired_version: int): - print("Property", desired_property_name, "updated to", str(desired_property_value), "version", desired_version) +def device_twin_desired_updated( + desired_property_name: str, desired_property_value, desired_version: int +): + print( + "Property", + desired_property_name, + "updated to", + str(desired_property_value), + "version", + desired_version, + ) # Subscribe to the device twin desired property updated event From a7dd16c27e72ad94cd24045495e28424bfdad619 Mon Sep 17 00:00:00 2001 From: brentru Date: Tue, 19 May 2020 15:28:37 -0400 Subject: [PATCH 2/4] black! --- adafruit_azureiot/device_registration.py | 45 ++-------- adafruit_azureiot/iot_mqtt.py | 104 +++++------------------ adafruit_azureiot/iotcentral_device.py | 43 ++-------- adafruit_azureiot/iothub_device.py | 58 +++---------- docs/conf.py | 18 +--- examples/iotcentral_commands.py | 8 +- examples/iotcentral_notconnected.py | 8 +- examples/iotcentral_properties.py | 15 +--- examples/iotcentral_simpletest.py | 8 +- examples/iothub_directmethods.py | 4 +- examples/iothub_messages.py | 4 +- examples/iothub_simpletest.py | 4 +- examples/iothub_twin_operations.py | 15 +--- 13 files changed, 66 insertions(+), 268 deletions(-) diff --git a/adafruit_azureiot/device_registration.py b/adafruit_azureiot/device_registration.py index a0f6063..dc83ab3 100644 --- a/adafruit_azureiot/device_registration.py +++ b/adafruit_azureiot/device_registration.py @@ -72,13 +72,9 @@ def _parse_http_status(status_code: int, status_reason: str) -> None: """ for error in AZURE_HTTP_ERROR_CODES: if error == status_code: - raise DeviceRegistrationError( - "Error {0}: {1}".format(status_code, status_reason) - ) + raise DeviceRegistrationError("Error {0}: {1}".format(status_code, status_reason)) - def __init__( - self, socket, id_scope: str, device_id: str, key: str, logger: Logger = None - ): + def __init__(self, socket, id_scope: str, device_id: str, key: str, 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 @@ -102,9 +98,7 @@ def compute_derived_symmetric_key(secret: str, msg: str) -> bytes: :rtype: bytes """ secret = base64.b64decode(secret) - return base64.b64encode( - hmac.new(secret, msg=msg.encode("utf8"), digestmod=hashlib.sha256).digest() - ) + return base64.b64encode(hmac.new(secret, msg=msg.encode("utf8"), digestmod=hashlib.sha256).digest()) def _loop_assign(self, operation_id, headers) -> str: uri = "https://%s/%s/registrations/%s/operations/%s?api-version=%s" % ( @@ -161,10 +155,7 @@ def _run_put_request_with_retry(self, url, body, headers): self._logger.debug("Sent!") break except RuntimeError as runtime_error: - self._logger.info( - "Could not send data, retrying after 0.5 seconds: " - + str(runtime_error) - ) + self._logger.info("Could not send data, retrying after 0.5 seconds: " + str(runtime_error)) retry = retry + 1 if retry >= 10: @@ -189,10 +180,7 @@ def _run_get_request_with_retry(self, url, headers): self._logger.debug("Sent!") break except RuntimeError as runtime_error: - self._logger.info( - "Could not send data, retrying after 0.5 seconds: " - + str(runtime_error) - ) + self._logger.info("Could not send data, retrying after 0.5 seconds: " + str(runtime_error)) retry = retry + 1 if retry >= 10: @@ -217,19 +205,9 @@ def register_device(self, expiry: int) -> str: """ # pylint: disable=C0103 sr = self._id_scope + "%2Fregistrations%2F" + self._device_id - sig_no_encode = DeviceRegistration.compute_derived_symmetric_key( - self._key, sr + "\n" + str(expiry) - ) + sig_no_encode = DeviceRegistration.compute_derived_symmetric_key(self._key, sr + "\n" + str(expiry)) sig_encoded = parse.quote(sig_no_encode, "~()*!.'") - auth_string = ( - "SharedAccessSignature sr=" - + sr - + "&sig=" - + sig_encoded - + "&se=" - + str(expiry) - + "&skn=registration" - ) + auth_string = "SharedAccessSignature sr=" + sr + "&sig=" + sig_encoded + "&se=" + str(expiry) + "&skn=registration" headers = { "content-type": "application/json; charset=utf-8", @@ -260,14 +238,7 @@ def register_device(self, expiry: int) -> str: try: data = response.json() except ValueError as error: - err = ( - "ERROR: non JSON is received from " - + constants.DPS_END_POINT - + " => " - + str(response) - + " .. message : " - + str(error) - ) + err = "ERROR: non JSON is received from " + constants.DPS_END_POINT + " => " + str(response) + " .. message : " + str(error) self._logger.error(err) raise DeviceRegistrationError(err) diff --git a/adafruit_azureiot/iot_mqtt.py b/adafruit_azureiot/iot_mqtt.py index 698cd35..96f7bb8 100644 --- a/adafruit_azureiot/iot_mqtt.py +++ b/adafruit_azureiot/iot_mqtt.py @@ -84,21 +84,14 @@ def cloud_to_device_message_received(self, body: str, properties: dict) -> None: :param dict properties: The propreties sent with the mesage """ - def device_twin_desired_updated( - self, desired_property_name: str, desired_property_value, desired_version: int - ) -> None: + 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 """ - def device_twin_reported_updated( - self, - reported_property_name: str, - reported_property_value, - reported_version: int, - ) -> None: + def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, 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 @@ -114,17 +107,11 @@ class IoTMQTT: def _gen_sas_token(self) -> str: token_expiry = int(time.time() + self._token_expires) uri = self._hostname + "%2Fdevices%2F" + self._device_id - signed_hmac_sha256 = DeviceRegistration.compute_derived_symmetric_key( - self._key, uri + "\n" + str(token_expiry) - ) + signed_hmac_sha256 = DeviceRegistration.compute_derived_symmetric_key(self._key, uri + "\n" + str(token_expiry)) signature = parse.quote(signed_hmac_sha256, "~()*!.'") - if signature.endswith( - "\n" - ): # somewhere along the crypto chain a newline is inserted + if signature.endswith("\n"): # somewhere along the crypto chain a newline is inserted signature = signature[:-1] - token = "SharedAccessSignature sr={}&sig={}&se={}".format( - uri, signature, token_expiry - ) + token = "SharedAccessSignature sr={}&sig={}&se={}".format(uri, signature, token_expiry) return token # Workaround for https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/issues/25 @@ -160,12 +147,7 @@ def _create_mqtt_client(self) -> None: # pylint: disable=C0103, W0613 def _on_connect(self, client, userdata, _, rc) -> None: - self._logger.info( - "- iot_mqtt :: _on_connect :: rc = " - + str(rc) - + ", userdata = " - + str(userdata) - ) + self._logger.info("- iot_mqtt :: _on_connect :: rc = " + str(rc) + ", userdata = " + str(userdata)) if rc == 0: self._mqtt_connected = True self._auth_response_received = True @@ -192,9 +174,7 @@ def _on_disconnect(self, client, userdata, rc) -> None: self._callback.connection_status_change(False) def _on_publish(self, client, data, topic, msg_id) -> None: - self._logger.info( - "- iot_mqtt :: _on_publish :: " + str(data) + " on topic " + str(topic) - ) + self._logger.info("- iot_mqtt :: _on_publish :: " + str(data) + " on topic " + str(topic)) # pylint: disable=W0703 def _handle_device_twin_update(self, msg: str, topic: str) -> None: @@ -205,12 +185,7 @@ def _handle_device_twin_update(self, msg: str, topic: str) -> None: try: twin = json.loads(msg) except json.JSONDecodeError as e: - self._logger.error( - "ERROR: JSON parse for Device Twin message object has failed. => " - + msg - + " => " - + str(e) - ) + self._logger.error("ERROR: JSON parse for Device Twin message object has failed. => " + msg + " => " + str(e)) return if "reported" in twin: @@ -220,15 +195,11 @@ def _handle_device_twin_update(self, msg: str, topic: str) -> None: reported_version = reported["$version"] reported.pop("$version") else: - self._logger.error( - "ERROR: Unexpected payload for reported twin update => " + msg - ) + self._logger.error("ERROR: Unexpected payload for reported twin update => " + msg) return for property_name, value in reported.items(): - self._callback.device_twin_reported_updated( - property_name, value, reported_version - ) + self._callback.device_twin_reported_updated(property_name, value, reported_version) is_patch = "desired" not in twin @@ -241,15 +212,11 @@ def _handle_device_twin_update(self, msg: str, topic: str) -> None: desired_version = desired["$version"] desired.pop("$version") else: - self._logger.error( - "ERROR: Unexpected payload for desired twin update => " + msg - ) + self._logger.error("ERROR: Unexpected payload for desired twin update => " + msg) return for property_name, value in desired.items(): - self._callback.device_twin_desired_updated( - property_name, value, desired_version - ) + self._callback.device_twin_desired_updated(property_name, value, desired_version) def _handle_direct_method(self, msg: str, topic: str) -> None: index = topic.find("$rid=") @@ -278,14 +245,7 @@ def _handle_direct_method(self, msg: str, topic: str) -> None: ret_message = json.dumps(ret_json) next_topic = "$iothub/methods/res/{}/?$rid={}".format(ret_code, method_id) - self._logger.info( - "C2D: => " - + next_topic - + " with data " - + ret_message - + " and name => " - + method_name - ) + self._logger.info("C2D: => " + next_topic + " with data " + ret_message + " and name => " + method_name) self._send_common(next_topic, ret_message) def _handle_cloud_to_device_message(self, msg: str, topic: str) -> None: @@ -318,18 +278,14 @@ def _on_message(self, client, msg_topic, payload) -> None: topic = str(msg_topic) if topic.startswith("$iothub/"): - if topic.startswith( - "$iothub/twin/PATCH/properties/desired/" - ) or topic.startswith("$iothub/twin/res/200/?$rid="): + if topic.startswith("$iothub/twin/PATCH/properties/desired/") or topic.startswith("$iothub/twin/res/200/?$rid="): self._handle_device_twin_update(str(msg), topic) elif topic.startswith("$iothub/methods"): self._handle_direct_method(str(msg), topic) else: if not topic.startswith("$iothub/twin/res/"): # not twin response self._logger.error("ERROR: unknown twin! - {}".format(msg)) - elif topic.startswith( - "devices/{}/messages/devicebound".format(self._device_id) - ): + elif topic.startswith("devices/{}/messages/devicebound".format(self._device_id)): self._handle_cloud_to_device_message(str(msg), topic) else: self._logger.error("ERROR: (unknown message) - {}".format(msg)) @@ -355,10 +311,7 @@ def _send_common(self, topic: str, data) -> None: self._logger.debug("Data sent") break except RuntimeError as runtime_error: - self._logger.info( - "Could not send data, retrying after 0.5 seconds: " - + str(runtime_error) - ) + self._logger.info("Could not send data, retrying after 0.5 seconds: " + str(runtime_error)) retry = retry + 1 if retry >= 10: @@ -407,24 +360,18 @@ def __init__( self._hostname = hostname self._key = key self._token_expires = token_expires - self._username = "{}/{}/api-version={}".format( - self._hostname, device_id, constants.IOTC_API_VERSION - ) + self._username = "{}/{}/api-version={}".format(self._hostname, device_id, constants.IOTC_API_VERSION) self._passwd = self._gen_sas_token() self._logger = logger if logger is not None else logging.getLogger("log") self._is_subscribed_to_twins = False def _subscribe_to_core_topics(self): self._mqtts.subscribe("devices/{}/messages/events/#".format(self._device_id)) - self._mqtts.subscribe( - "devices/{}/messages/devicebound/#".format(self._device_id) - ) + self._mqtts.subscribe("devices/{}/messages/devicebound/#".format(self._device_id)) self._mqtts.subscribe("$iothub/methods/#") def _subscribe_to_twin_topics(self): - self._mqtts.subscribe( - "$iothub/twin/PATCH/properties/desired/#" - ) # twin desired property changes + self._mqtts.subscribe("$iothub/twin/PATCH/properties/desired/#") # twin desired property changes self._mqtts.subscribe("$iothub/twin/res/#") # twin properties response def connect(self) -> bool: @@ -440,10 +387,7 @@ def connect(self) -> bool: while self._auth_response_received is None: self.loop() - self._logger.info( - " - iot_mqtt :: connect :: on_connect must be fired. Connected ? " - + str(self.is_connected()) - ) + self._logger.info(" - iot_mqtt :: connect :: on_connect must be fired. Connected ? " + str(self.is_connected())) if not self.is_connected(): return False @@ -500,9 +444,7 @@ def loop(self) -> None: self._mqtts.loop() - def send_device_to_cloud_message( - self, message, system_properties: dict = None - ) -> None: + 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 @@ -538,7 +480,5 @@ def send_twin_patch(self, patch) -> None: :raises RuntimeError: if the internet connection is not responding or is unable to connect """ self._logger.info("- iot_mqtt :: sendProperty :: " + str(patch)) - topic = "$iothub/twin/PATCH/properties/reported/?$rid={}".format( - int(time.time()) - ) + topic = "$iothub/twin/PATCH/properties/reported/?$rid={}".format(int(time.time())) self._send_common(topic, patch) diff --git a/adafruit_azureiot/iotcentral_device.py b/adafruit_azureiot/iotcentral_device.py index 23fe9d1..94c4206 100644 --- a/adafruit_azureiot/iotcentral_device.py +++ b/adafruit_azureiot/iotcentral_device.py @@ -62,9 +62,7 @@ def direct_method_called(self, method_name: str, payload: str) -> IoTResponse: raise IoTError("on_command_executed not set") - def device_twin_desired_updated( - self, desired_property_name: str, desired_property_value, desired_version: int - ) -> None: + 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 @@ -72,19 +70,12 @@ def device_twin_desired_updated( """ if self.on_property_changed is not None: # pylint: disable=E1102 - self.on_property_changed( - desired_property_name, desired_property_value, desired_version - ) + self.on_property_changed(desired_property_name, desired_property_value, desired_version) # when a desired property changes, update the reported to match to keep them in sync self.send_property(desired_property_name, desired_property_value) - def device_twin_reported_updated( - self, - reported_property_name: str, - reported_property_value, - reported_version: int, - ) -> None: + def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, 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 @@ -92,20 +83,11 @@ def device_twin_reported_updated( """ if self.on_property_changed is not None: # pylint: disable=E1102 - self.on_property_changed( - reported_property_name, reported_property_value, reported_version - ) + self.on_property_changed(reported_property_name, reported_property_value, reported_version) # pylint: disable=R0913 def __init__( - self, - socket, - iface, - id_scope: str, - device_id: str, - key: str, - token_expires: int = 21600, - logger: logging = None, + self, socket, iface, id_scope: str, device_id: str, key: str, token_expires: int = 21600, logger: logging = None, ): """Create the Azure IoT Central device client :param socket: The network socket @@ -152,22 +134,11 @@ def connect(self) -> None: :raises DeviceRegistrationError: if the device cannot be registered successfully :raises RuntimeError: if the internet connection is not responding or is unable to connect """ - self._device_registration = DeviceRegistration( - self._socket, self._id_scope, self._device_id, self._key, self._logger - ) + self._device_registration = DeviceRegistration(self._socket, self._id_scope, self._device_id, self._key, self._logger) token_expiry = int(time.time() + self._token_expires) hostname = self._device_registration.register_device(token_expiry) - self._mqtt = IoTMQTT( - self, - self._socket, - self._iface, - hostname, - self._device_id, - self._key, - self._token_expires, - self._logger, - ) + self._mqtt = IoTMQTT(self, self._socket, self._iface, hostname, self._device_id, self._key, self._token_expires, self._logger,) self._mqtt.connect() self._mqtt.subscribe_to_twins() diff --git a/adafruit_azureiot/iothub_device.py b/adafruit_azureiot/iothub_device.py index 6ccaf79..faca152 100755 --- a/adafruit_azureiot/iothub_device.py +++ b/adafruit_azureiot/iothub_device.py @@ -108,9 +108,7 @@ def cloud_to_device_message_received(self, body: str, properties: dict) -> None: # pylint: disable=E1102 self._on_cloud_to_device_message_received(body, properties) - def device_twin_desired_updated( - self, desired_property_name: str, desired_property_value, desired_version: int - ) -> None: + 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 @@ -118,16 +116,9 @@ def device_twin_desired_updated( """ if self._on_device_twin_desired_updated is not None: # pylint: disable=E1102 - self._on_device_twin_desired_updated( - desired_property_name, desired_property_value, desired_version - ) - - def device_twin_reported_updated( - self, - reported_property_name: str, - reported_property_value, - reported_version: int, - ) -> None: + self._on_device_twin_desired_updated(desired_property_name, desired_property_value, desired_version) + + def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, 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 @@ -135,17 +126,10 @@ def device_twin_reported_updated( """ if self._on_device_twin_reported_updated is not None: # pylint: disable=E1102 - self._on_device_twin_reported_updated( - reported_property_name, reported_property_value, reported_version - ) + self._on_device_twin_reported_updated(reported_property_name, reported_property_value, reported_version) def __init__( - self, - socket, - iface, - device_connection_string: str, - token_expires: int = 21600, - logger: logging = None, + self, socket, iface, device_connection_string: str, token_expires: int = 21600, logger: logging = None, ): """Create the Azure IoT Central device client :param socket: The network socket @@ -163,13 +147,9 @@ def __init__( try: cs_args = device_connection_string.split(DELIMITER) - connection_string_values = dict( - arg.split(VALUE_SEPARATOR, 1) for arg in cs_args - ) + connection_string_values = dict(arg.split(VALUE_SEPARATOR, 1) for arg in cs_args) except (ValueError, AttributeError): - raise ValueError( - "Connection string is required and should not be empty or blank and must be supplied as a string" - ) + raise ValueError("Connection string is required and should not be empty or blank and must be supplied as a string") if len(cs_args) != len(connection_string_values): raise ValueError("Invalid Connection String - Unable to parse") @@ -240,15 +220,11 @@ def cloud_to_device_message_received(body: str, properties: dict) -> None: return self._on_cloud_to_device_message_received @on_cloud_to_device_message_received.setter - def on_cloud_to_device_message_received( - self, new_on_cloud_to_device_message_received - ): + def on_cloud_to_device_message_received(self, new_on_cloud_to_device_message_received): """A callback method that is called when a cloud to device message is received. This method should have the following signature: def cloud_to_device_message_received(body: str, properties: dict) -> None: """ - self._on_cloud_to_device_message_received = ( - new_on_cloud_to_device_message_received - ) + self._on_cloud_to_device_message_received = new_on_cloud_to_device_message_received @property def on_device_twin_desired_updated(self): @@ -293,21 +269,11 @@ def connect(self) -> None: :raises RuntimeError: if the internet connection is not responding or is unable to connect """ self._mqtt = IoTMQTT( - self, - self._socket, - self._iface, - self._hostname, - self._device_id, - self._shared_access_key, - self._token_expires, - self._logger, + self, self._socket, self._iface, self._hostname, self._device_id, self._shared_access_key, self._token_expires, self._logger, ) self._mqtt.connect() - if ( - self._on_device_twin_desired_updated is not None - or self._on_device_twin_reported_updated is not None - ): + if self._on_device_twin_desired_updated is not None or self._on_device_twin_reported_updated is not None: self._mqtt.subscribe_to_twins() def disconnect(self) -> None: diff --git a/docs/conf.py b/docs/conf.py index 45a7416..c3ee31e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -142,28 +142,14 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ( - master_doc, - "AdafruitAzureIoTLibrary.tex", - "AdafruitAzureIoT Library Documentation", - author, - "manual", - ), + (master_doc, "AdafruitAzureIoTLibrary.tex", "AdafruitAzureIoT Library Documentation", author, "manual",), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ( - master_doc, - "AdafruitAzureIoTlibrary", - "Adafruit AzureIoT Library Documentation", - [author], - 1, - ) -] +man_pages = [(master_doc, "AdafruitAzureIoTlibrary", "Adafruit AzureIoT Library Documentation", [author], 1,)] # -- Options for Texinfo output ------------------------------------------- diff --git a/examples/iotcentral_commands.py b/examples/iotcentral_commands.py index a61d054..e8c3a56 100644 --- a/examples/iotcentral_commands.py +++ b/examples/iotcentral_commands.py @@ -28,9 +28,7 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -96,9 +94,7 @@ from adafruit_azureiot.iot_mqtt import IoTResponse # Create an IoT Hub device client and connect -device = IoTCentralDevice( - socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"] -) +device = IoTCentralDevice(socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"]) # Subscribe to commands # Commands can be sent from the devices Dashboard in IoT Central, assuming diff --git a/examples/iotcentral_notconnected.py b/examples/iotcentral_notconnected.py index d1a8289..4a9f4d6 100644 --- a/examples/iotcentral_notconnected.py +++ b/examples/iotcentral_notconnected.py @@ -30,9 +30,7 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -97,9 +95,7 @@ from adafruit_azureiot import IoTCentralDevice, IoTError # Create an IoT Hub device client and connect -device = IoTCentralDevice( - socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"] -) +device = IoTCentralDevice(socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"]) # don't connect # device.connect() diff --git a/examples/iotcentral_properties.py b/examples/iotcentral_properties.py index d251a20..b94cdaa 100644 --- a/examples/iotcentral_properties.py +++ b/examples/iotcentral_properties.py @@ -29,9 +29,7 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -96,21 +94,14 @@ from adafruit_azureiot import IoTCentralDevice # Create an IoT Hub device client and connect -device = IoTCentralDevice( - socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"] -) +device = IoTCentralDevice(socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"]) # Subscribe to property changes # Properties can be updated either in code, or by adding a form to the view # in the device template, and setting the value on the dashboard for the device def property_changed(property_name, property_value, version): print( - "Property", - property_name, - "updated to", - str(property_value), - "version", - str(version), + "Property", property_name, "updated to", str(property_value), "version", str(version), ) diff --git a/examples/iotcentral_simpletest.py b/examples/iotcentral_simpletest.py index ba9e328..571ee38 100644 --- a/examples/iotcentral_simpletest.py +++ b/examples/iotcentral_simpletest.py @@ -30,9 +30,7 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -97,9 +95,7 @@ from adafruit_azureiot import IoTCentralDevice # Create an IoT Hub device client and connect -device = IoTCentralDevice( - socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"] -) +device = IoTCentralDevice(socket, esp, secrets["id_scope"], secrets["device_id"], secrets["key"]) print("Connecting to Azure IoT Central...") diff --git a/examples/iothub_directmethods.py b/examples/iothub_directmethods.py index 9153349..341a51f 100644 --- a/examples/iothub_directmethods.py +++ b/examples/iothub_directmethods.py @@ -28,9 +28,7 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED diff --git a/examples/iothub_messages.py b/examples/iothub_messages.py index 7b6f517..52524b1 100644 --- a/examples/iothub_messages.py +++ b/examples/iothub_messages.py @@ -30,9 +30,7 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED diff --git a/examples/iothub_simpletest.py b/examples/iothub_simpletest.py index aba2da4..703190c 100644 --- a/examples/iothub_simpletest.py +++ b/examples/iothub_simpletest.py @@ -30,9 +30,7 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED diff --git a/examples/iothub_twin_operations.py b/examples/iothub_twin_operations.py index 9942c5a..538ae95 100644 --- a/examples/iothub_twin_operations.py +++ b/examples/iothub_twin_operations.py @@ -29,9 +29,7 @@ esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset) """Use below for Most Boards""" -status_light = neopixel.NeoPixel( - board.NEOPIXEL, 1, brightness=0.2 -) # Uncomment for Most Boards +status_light = neopixel.NeoPixel(board.NEOPIXEL, 1, brightness=0.2) # Uncomment for Most Boards """Uncomment below for ItsyBitsy M4""" # status_light = dotstar.DotStar(board.APA102_SCK, board.APA102_MOSI, 1, brightness=0.2) # Uncomment below for an externally defined RGB LED @@ -100,16 +98,9 @@ # To see these changes, update the desired properties for the device either in code # or in the Azure portal by selecting the device in the IoT Hub blade, selecting # Device Twin then adding or amending an entry in the 'desired' section -def device_twin_desired_updated( - desired_property_name: str, desired_property_value, desired_version: int -): +def device_twin_desired_updated(desired_property_name: str, desired_property_value, desired_version: int): print( - "Property", - desired_property_name, - "updated to", - str(desired_property_value), - "version", - desired_version, + "Property", desired_property_name, "updated to", str(desired_property_value), "version", desired_version, ) From 468de41a6b23928cec5f29aad1fa134c3981db15 Mon Sep 17 00:00:00 2001 From: Jim Bennett Date: Thu, 21 May 2020 17:39:21 -0700 Subject: [PATCH 3/4] Removing rogue commas to make the PR easier to read --- adafruit_azureiot/iotcentral_device.py | 8 +++----- adafruit_azureiot/iothub_device.py | 8 +++----- docs/conf.py | 7 +------ examples/iotcentral_properties.py | 4 +--- examples/iothub_twin_operations.py | 4 +--- 5 files changed, 9 insertions(+), 22 deletions(-) diff --git a/adafruit_azureiot/iotcentral_device.py b/adafruit_azureiot/iotcentral_device.py index 94c4206..43270cc 100644 --- a/adafruit_azureiot/iotcentral_device.py +++ b/adafruit_azureiot/iotcentral_device.py @@ -75,7 +75,7 @@ def device_twin_desired_updated(self, desired_property_name: str, desired_proper # when a desired property changes, update the reported to match to keep them in sync self.send_property(desired_property_name, desired_property_value) - def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, reported_version: int,) -> None: + def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, 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 @@ -86,9 +86,7 @@ def device_twin_reported_updated(self, reported_property_name: str, reported_pro self.on_property_changed(reported_property_name, reported_property_value, reported_version) # pylint: disable=R0913 - def __init__( - self, socket, iface, id_scope: str, device_id: str, key: str, token_expires: int = 21600, logger: logging = None, - ): + def __init__(self, socket, iface, id_scope: str, device_id: str, key: str, token_expires: int = 21600, logger: logging = None): """Create the Azure IoT Central device client :param socket: The network socket :param iface: The network interface @@ -138,7 +136,7 @@ def connect(self) -> None: token_expiry = int(time.time() + self._token_expires) hostname = self._device_registration.register_device(token_expiry) - self._mqtt = IoTMQTT(self, self._socket, self._iface, hostname, self._device_id, self._key, self._token_expires, self._logger,) + self._mqtt = IoTMQTT(self, self._socket, self._iface, hostname, self._device_id, self._key, self._token_expires, self._logger) self._mqtt.connect() self._mqtt.subscribe_to_twins() diff --git a/adafruit_azureiot/iothub_device.py b/adafruit_azureiot/iothub_device.py index faca152..c7900d6 100755 --- a/adafruit_azureiot/iothub_device.py +++ b/adafruit_azureiot/iothub_device.py @@ -118,7 +118,7 @@ def device_twin_desired_updated(self, desired_property_name: str, desired_proper # pylint: disable=E1102 self._on_device_twin_desired_updated(desired_property_name, desired_property_value, desired_version) - def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, reported_version: int,) -> None: + def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, 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 @@ -128,9 +128,7 @@ def device_twin_reported_updated(self, reported_property_name: str, reported_pro # pylint: disable=E1102 self._on_device_twin_reported_updated(reported_property_name, reported_property_value, reported_version) - def __init__( - self, socket, iface, device_connection_string: str, token_expires: int = 21600, logger: logging = None, - ): + def __init__(self, socket, iface, device_connection_string: str, token_expires: int = 21600, logger: logging = None): """Create the Azure IoT Central device client :param socket: The network socket :param iface: The network interface @@ -269,7 +267,7 @@ def connect(self) -> None: :raises RuntimeError: if the internet connection is not responding or is unable to connect """ self._mqtt = IoTMQTT( - self, self._socket, self._iface, self._hostname, self._device_id, self._shared_access_key, self._token_expires, self._logger, + self, self._socket, self._iface, self._hostname, self._device_id, self._shared_access_key, self._token_expires, self._logger ) self._mqtt.connect() diff --git a/docs/conf.py b/docs/conf.py index c3ee31e..41677b7 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -21,12 +21,7 @@ # Uncomment the below if you use native CircuitPython modules such as # digitalio, micropython and busio. List the modules you use. Without it, the # autodoc module docs will fail to generate with a warning. -autodoc_mock_imports = [ - "adafruit_logging", - "adafruit_requests", - "adafruit_hashlib", - "adafruit_ntp", -] +autodoc_mock_imports = ["adafruit_logging", "adafruit_requests", "adafruit_hashlib", "adafruit_ntp"] intersphinx_mapping = { diff --git a/examples/iotcentral_properties.py b/examples/iotcentral_properties.py index b94cdaa..15dde99 100644 --- a/examples/iotcentral_properties.py +++ b/examples/iotcentral_properties.py @@ -100,9 +100,7 @@ # Properties can be updated either in code, or by adding a form to the view # in the device template, and setting the value on the dashboard for the device def property_changed(property_name, property_value, version): - print( - "Property", property_name, "updated to", str(property_value), "version", str(version), - ) + print("Property", property_name, "updated to", str(property_value), "version", str(version)) # Subscribe to the property changed event diff --git a/examples/iothub_twin_operations.py b/examples/iothub_twin_operations.py index 538ae95..83ef88b 100644 --- a/examples/iothub_twin_operations.py +++ b/examples/iothub_twin_operations.py @@ -99,9 +99,7 @@ # or in the Azure portal by selecting the device in the IoT Hub blade, selecting # Device Twin then adding or amending an entry in the 'desired' section def device_twin_desired_updated(desired_property_name: str, desired_property_value, desired_version: int): - print( - "Property", desired_property_name, "updated to", str(desired_property_value), "version", desired_version, - ) + print("Property", desired_property_name, "updated to", str(desired_property_value), "version", desired_version) # Subscribe to the device twin desired property updated event From 17699e7d58e8128e1548ef2ee9eff68e913d79ac Mon Sep 17 00:00:00 2001 From: Jim Bennett Date: Thu, 21 May 2020 17:39:38 -0700 Subject: [PATCH 4/4] Removing try method and unnecessary comment --- adafruit_azureiot/iot_mqtt.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/adafruit_azureiot/iot_mqtt.py b/adafruit_azureiot/iot_mqtt.py index 96f7bb8..6f3d950 100644 --- a/adafruit_azureiot/iot_mqtt.py +++ b/adafruit_azureiot/iot_mqtt.py @@ -91,7 +91,7 @@ def device_twin_desired_updated(self, desired_property_name: str, desired_proper :param int desired_version: The version of the desired property that was updated """ - def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, reported_version: int,) -> None: + def device_twin_reported_updated(self, reported_property_name: str, reported_property_value, 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 @@ -114,12 +114,11 @@ def _gen_sas_token(self) -> str: token = "SharedAccessSignature sr={}&sig={}&se={}".format(uri, signature, token_expiry) return token - # Workaround for https://github.com/adafruit/Adafruit_CircuitPython_MiniMQTT/issues/25 - def _try_create_mqtt_client(self, hostname: str) -> None: + def _create_mqtt_client(self) -> None: minimqtt.set_socket(self._socket, self._iface) self._mqtts = MQTT( - broker=hostname, + broker=self._hostname, username=self._username, password=self._passwd, port=8883, @@ -142,9 +141,6 @@ def _try_create_mqtt_client(self, hostname: str) -> None: self._mqtts.last_will() self._mqtts.connect() - def _create_mqtt_client(self) -> None: - self._try_create_mqtt_client(self._hostname) - # pylint: disable=C0103, W0613 def _on_connect(self, client, userdata, _, rc) -> None: self._logger.info("- iot_mqtt :: _on_connect :: rc = " + str(rc) + ", userdata = " + str(userdata))