def iothub_devicemethod_sample_run( callback_method: str = "start_fan", callback_payload: dict = {}, ): """Simulate a cloud-to-device message to an IoT device to run a method. Args: callback_method (str, optional): Function that will be called on the IoT Device. Defaults to `start_fan`. callback_payload (dict, optional): additional data that can be processed by the IoT Device. Defaults to `{}`. """ try: # Create IoTHubRegistryManager registry_manager = IoTHubRegistryManager(CONNECTION_STRING) # Call the direct method. deviceMethod = CloudToDeviceMethod(method_name=callback_method, payload=callback_payload) response = registry_manager.invoke_device_method( DEVICE_ID, deviceMethod) print("") print("Device Method called") print("Device Method name : {0}".format(callback_method)) print("Device Method payload : {0}".format(callback_payload)) print("") print("Response status : {0}".format(response.status)) print("Response payload : {0}".format(response.payload)) input("Press Enter to continue...\n") except KeyboardInterrupt: print("") print("IoTHubDeviceMethod sample stopped")
def iot_device_updatetelemetry_interval(): # Try-except in use as webservice may fail try: # Create registry manager registry_manager = IoTHubRegistryManager(connection_string) # Call the direct method device_method = CloudToDeviceMethod(method_name=method_name, payload=method_payload) device_response = registry_manager.invoke_device_method( device_id, device_method) # Provide feedback to user print("") print("Device Method Called") print("Device Method Name : {0}".format(method_name)) print("Device Method Payload : {0}".format(method_payload)) print("Device Response") print("Response Status : {0}".format(device_response.status)) print("Response Payload : {0}".format(device_response.payload)) # Allow user to close service connection input("Press Enter to continue ...\n") except Exception as ex: print("Unexpected error") return except KeyboardInterrupt: print("Device Instruction stopped")
def iothub_devicemethod_sample_run(): try: # Create IoTHubRegistryManager registry_manager = IoTHubRegistryManager(CONNECTION_STRING) # Call the direct method. deviceMethod = CloudToDeviceMethod(method_name=METHOD_NAME, payload=METHOD_PAYLOAD) response = registry_manager.invoke_device_method(DEVICE_ID, deviceMethod) print ( "" ) print ( "Device Method called" ) print ( "Device Method name : {0}".format(METHOD_NAME) ) print ( "Device Method payload : {0}".format(METHOD_PAYLOAD) ) print ( "" ) print ( "Response status : {0}".format(response.status) ) print ( "Response payload : {0}".format(response.payload) ) input("Press Enter to continue...\n") except Exception as ex: print ( "" ) print ( "Unexpected error {0}".format(ex) ) return except KeyboardInterrupt: print ( "" ) print ( "IoTHubDeviceMethod sample stopped" )
def call_method(method_name, param): # Create IoTHubRegistryManager registry_manager = IoTHubRegistryManager(CONNECTION_STRING) # Call the direct method. deviceMethod = CloudToDeviceMethod(method_name=method_name, payload=param) response = registry_manager.invoke_device_method(DEVICE_ID, deviceMethod)
def main(msg: func.ServiceBusMessage): """When a message arrives on the servicebus, send a trigger to IoT Hub to start the fan for that device. Args: msg (func.ServiceBusMessage): Message from the connected Queue in a Azure ServiceBus """ # Extract the method into a dictionary msg_dict = json.loads(msg.get_body().decode("utf-8")) logging.info( f"Python ServiceBus queue trigger processed message: {msg_dict}") # Enable a connection with the IoT Hub. The connectionstring for the IoT Hub # is preloaded in the Azure Functions configurations. connectino_string_iothub = os.getenv("connectionStringIotHub") registry_manager = IoTHubRegistryManager(connectino_string_iothub) # Settings for the method that the IoT Device should run upon receiving the message. callback_method = "start_fan" callback_payload = {} device_method = CloudToDeviceMethod(method_name=callback_method, payload=callback_payload) # Sending the actual cloud-to-device message and invoke a function on the IoT device. device_id = msg_dict["IoTHub"]["ConnectionDeviceId"] response = registry_manager.invoke_device_method(device_id, device_method) print("") print("Device Method called") print("Device Method name : {0}".format(callback_method)) print("Device Method payload : {0}".format(callback_payload)) print("") print("Response status : {0}".format(response.status)) print("Response payload : {0}".format(response.payload))
class ServiceHelperSync(object): def __init__(self): self._executor = ThreadPoolExecutor() self._registry_manager = IoTHubRegistryManager( iothub_connection_string) logger.info( "Creating EventHubConsumerClient with consumer_group = {}".format( eventhub_consumer_group)) self._eventhub_consumer_client = EventHubConsumerClient.from_connection_string( eventhub_connection_string, consumer_group=eventhub_consumer_group) self._eventhub_future = self._executor.submit(self._eventhub_thread) self.device_id = None self.module_id = None self.incoming_patch_queue = queue.Queue() self.cv = threading.Condition() self.incoming_eventhub_events = {} def set_identity(self, device_id, module_id): if device_id != self.device_id or module_id != self.module_id: self.device_id = device_id self.module_id = module_id self.incoming_patch_queue = queue.Queue() with self.cv: if self.incoming_eventhub_events: logger.warning( "Abandoning incoming events with IDs {}".format( str(list(self.incoming_eventhub_events.keys())))) self.incoming_eventhub_events = {} def set_desired_properties(self, desired_props): if self.module_id: self._registry_manager.update_module_twin( self.device_id, self.module_id, Twin(properties=TwinProperties(desired=desired_props)), "*", ) else: self._registry_manager.update_twin( self.device_id, Twin(properties=TwinProperties(desired=desired_props)), "*") def invoke_method( self, method_name, payload, connect_timeout_in_seconds=30, response_timeout_in_seconds=None, ): request = CloudToDeviceMethod( method_name=method_name, payload=payload, response_timeout_in_seconds=response_timeout_in_seconds, connect_timeout_in_seconds=connect_timeout_in_seconds, ) if self.module_id: response = self._registry_manager.invoke_device_module_method( self.device_id, self.module_id, request) else: response = self._registry_manager.invoke_device_method( self.device_id, request) return response def send_c2d(self, payload, properties): if self.module_id: raise TypeError("sending C2D to modules is not supported") self._registry_manager.send_c2d_message(self.device_id, payload, properties) def wait_for_eventhub_arrival(self, message_id, timeout=600): def get_event(inner_message_id): with self.cv: arrivals = self.incoming_eventhub_events # if message_id is not set, return any message if not inner_message_id and len(arrivals): id = list(arrivals.keys())[0] logger.info( "wait_for_eventhub_arrival(None) returning msgid={}". format(id)) else: id = inner_message_id if id and (id in arrivals): value = arrivals[id] del arrivals[id] return value else: return None if timeout: end_time = time.time() + timeout else: end_time = None with self.cv: while True: ev = get_event(message_id) if ev: return ev elif time.time() >= end_time: logger.warning( "timeout waiting for message with msgid={}".format( message_id)) return None elif end_time: self.cv.wait(timeout=end_time - time.time()) else: self.cv.wait() def get_next_reported_patch_arrival(self, block=True, timeout=20): try: return self.incoming_patch_queue.get(block=block, timeout=timeout) except queue.Empty: raise Exception( "reported patch did not arrive within {} seconds".format( timeout)) def shutdown(self): if self._eventhub_consumer_client: self._eventhub_consumer_client.close() def _convert_incoming_event(self, event): try: event_body = event.body_as_json() except TypeError: event_body = event.body_as_str() device_id = get_device_id_from_event(event) module_id = get_module_id_from_event(event) if get_message_source_from_event(event) == "twinChangeEvents": return copy.deepcopy(event_body.get("properties", {})) else: message = EventhubEvent() message.device_id = device_id message.module_id = module_id message.message_body = event_body if event.message.properties: message.properties = convert_binary_dict_to_string_dict( event.properties) message.content_type = event.message.properties.content_type.decode( "utf-8") message.system_properties = convert_binary_dict_to_string_dict( event.system_properties) return message def _store_eventhub_arrival(self, converted_event): message_id = converted_event.system_properties.get( "message-id", "no-message-id-{}".format(uuid.uuid4())) if message_id: with self.cv: self.incoming_eventhub_events[message_id] = converted_event self.cv.notify_all() def _store_patch_arrival(self, converted_event): self.incoming_patch_queue.put(converted_event) def _eventhub_thread(self): def on_error(partition_context, error): logger.error("EventHub on_error: {}".format( str(error) or type(error))) def on_partition_initialize(partition_context): logger.warning("EventHub on_partition_initialize") def on_partition_close(partition_context, reason): logger.warning("EventHub on_partition_close: {}".format(reason)) def on_event_batch(partition_context, events): try: for event in events: device_id = get_device_id_from_event(event) module_id = get_module_id_from_event(event) if device_id == self.device_id and module_id == self.module_id: converted_event = self._convert_incoming_event(event) if type(converted_event) == EventhubEvent: if "message-id" in converted_event.system_properties: logger.info( "Received event with msgid={}".format( converted_event. system_properties["message-id"])) else: logger.info( "Received event with no message id") else: logger.info( "Received {} for device {}, module {}".format( get_message_source_from_event(event), device_id, module_id, )) if isinstance(converted_event, EventhubEvent): self._store_eventhub_arrival(converted_event) else: self._store_patch_arrival(converted_event) except Exception: logger.error("Error on on_event_batch", exc_info=True) raise try: with self._eventhub_consumer_client: logger.info("Starting EventHub receive") self._eventhub_consumer_client.receive_batch( max_wait_time=2, on_event_batch=on_event_batch, on_error=on_error, on_partition_initialize=on_partition_initialize, on_partition_close=on_partition_close, ) except Exception: logger.error("_eventhub_thread exception", exc_info=True) raise
class ServiceHelperSync(object): def __init__(self): self._client_list = ClientList() self._executor = ThreadPoolExecutor() self._registry_manager = IoTHubRegistryManager( iothub_connection_string) self._digital_twin_client = DigitalTwinClient.from_connection_string( iothub_connection_string) self._eventhub_consumer_client = EventHubConsumerClient.from_connection_string( eventhub_connection_string, consumer_group=eventhub_consumer_group) self._eventhub_future = self._executor.submit(self._eventhub_thread) def start_watching(self, device_id, module_id): self._client_list.get_or_create(device_id, module_id) def stop_watching(self, device_id, module_id): self._client_list.remove(device_id, module_id) def get_next_incoming_event(self, device_id, module_id, block=True, timeout=None): return self._client_list.get_incoming_event_queue.get(block=block, timeout=timeout) def set_desired_properties(self, device_id, module_id, desired_props): if module_id: self._registry_manager.update_module_twin( device_id, module_id, Twin(properties=TwinProperties(desired=desired_props)), "*") else: self._registry_manager.update_twin( device_id, Twin(properties=TwinProperties(desired=desired_props)), "*") def invoke_method( self, device_id, module_id, method_name, payload, connect_timeout_in_seconds=None, response_timeout_in_seconds=None, ): request = CloudToDeviceMethod( method_name=method_name, payload=payload, response_timeout_in_seconds=response_timeout_in_seconds, connect_timeout_in_seconds=connect_timeout_in_seconds, ) if module_id: response = self._registry_manager.invoke_device_module_method( device_id, module_id, request) else: response = self._registry_manager.invoke_device_method( device_id, request) return response def invoke_pnp_command( self, device_id, module_id, component_name, command_name, payload, connect_timeout_in_seconds=None, response_timeout_in_seconds=None, ): assert not module_id # TODO if component_name: return self._digital_twin_client.invoke_component_command( device_id, component_name, command_name, payload, connect_timeout_in_seconds, response_timeout_in_seconds, ) else: return self._digital_twin_client.invoke_command( device_id, command_name, payload, connect_timeout_in_seconds, response_timeout_in_seconds, ) def get_pnp_properties(self, device_id, module_id): assert not module_id # TODO return self._digital_twin_client.get_digital_twin(device_id) def update_pnp_properties(self, device_id, module_id, properties): assert not module_id # TODO return self._digital_twin_client.update_digital_twin( device_id, properties) def send_c2d(self, device_id, module_id, payload, properties): assert not module_id # TODO self._registry_manager.send_c2d_message(device_id, payload, properties) def get_next_eventhub_arrival(self, device_id, module_id, block=True, timeout=None): return self._client_list.get_incoming_event_queue( device_id, module_id).get(block=block, timeout=timeout) def get_next_reported_patch_arrival(self, device_id, module_id, block=True, timeout=None): return self._client_list.get_incoming_patch_queue( device_id, module_id).get(block=block, timeout=timeout) def shutdown(self): if self._eventhub_consumer_client: self._eventhub_consumer_client.close() def _convert_incoming_event(self, event): event_body = event.body_as_json() device_id = get_device_id_from_event(event) module_id = None # TODO: extract module_id if get_message_source_from_event(event) == "twinChangeEvents": return copy.deepcopy(event_body.get("properties", {})) else: message = C2dMessage() message.device_id = device_id message.module_id = module_id message.message_body = event_body message.content_type = event.message.properties.content_type.decode( "utf-8") message.system_properties = convert_binary_dict_to_string_dict( event.system_properties) message.properties = convert_binary_dict_to_string_dict( event.properties) return message def _eventhub_thread(self): def on_error(partition_context, error): logger.error("EventHub on_error: {}".format( str(error) or type(error))) def on_partition_initialize(partition_context): logger.warning("EventHub on_partition_initialize") def on_partition_close(partition_context, reason): # commented out because it causes ugly warning spew on shutdown # logger.warning("EventHub on_partition_close: {}".format(reason)) pass def on_event(partition_context, event): if event: device_id = get_device_id_from_event(event) module_id = None # TODO: extract module_id if get_message_source_from_event(event) == "twinChangeEvents": queue = self._client_list.get_incoming_patch_queue( device_id, module_id) else: queue = self._client_list.get_incoming_event_queue( device_id, module_id) if queue: logger.info("Received {} for device {}, module {}".format( get_message_source_from_event(event), device_id, module_id)) queue.put(self._convert_incoming_event(event)) try: with self._eventhub_consumer_client: logger.info("Starting EventHub receive") self._eventhub_consumer_client.receive( on_event, on_error=on_error, on_partition_initialize=on_partition_initialize, on_partition_close=on_partition_close, max_wait_time=3600, ) except Exception: logger.error("_eventhub_thread exception", exc_info=True) raise
# ------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. See License.txt in the project root for # license information. # -------------------------------------------------------------------------- import sys import os from azure.iot.hub import IoTHubRegistryManager from azure.iot.hub.models import CloudToDeviceMethod iothub_connection_str = os.getenv("IOTHUB_CONNECTION_STRING") device_id = os.getenv("IOTHUB_DEVICE_ID") method_name = "lockDoor" method_payload = "now" try: # Create IoTHubRegistryManager registry_manager = IoTHubRegistryManager(iothub_connection_str) deviceMethod = CloudToDeviceMethod(method_name=method_name, payload=method_payload) registry_manager.invoke_device_method(device_id, deviceMethod) except Exception as ex: print("Unexpected error {0}".format(ex)) except KeyboardInterrupt: print("iothub_registry_manager_sample stopped")
print("") # Print the device's model ID additional_props = twin.additional_properties if "modelId" in additional_props: print("The Model ID for this device is:") print(additional_props["modelId"]) print("") # Update twin twin_patch = Twin() twin_patch.properties = TwinProperties( desired={"targetTemperature": 42}) # this is relevant for the thermostat device sample updated_twin = iothub_registry_manager.update_twin(device_id, twin_patch, twin.etag) print("The twin patch has been successfully applied") print("") # invoke device method device_method = CloudToDeviceMethod(method_name=method_name, payload=method_payload) iothub_registry_manager.invoke_device_method(device_id, device_method) print("The device method has been successfully invoked") print("") except Exception as ex: print("Unexpected error {0}".format(ex)) except KeyboardInterrupt: print("iothub_registry_manager_sample stopped")
method_payload = "{}" if method_selection ==2: method_name = "Get_Send_Data_info" method_payload = "{}" if method_selection ==3: firmware_version_set = float(input("Please Set a Firmware Version: ")) method_name = "FW_Update" method_payload = firmware_version_set if method_selection ==4: method_name = "Other_Method" method_payload = "{}" registry_manager = IoTHubRegistryManager(connection_str) deviceMethod = CloudToDeviceMethod(method_name=method_name, payload=method_payload) method_response = registry_manager.invoke_device_method(device_id, deviceMethod) print(method_response) except Exception as ex: print("Unexpected error {0}".format(ex)) except KeyboardInterrupt: print("iothub_registry_manager_sample stopped") if defined_device_option == 6: # Send C2D Message try: send_message = input("Please input a message send to Device: ") # Create IoTHubRegistryManager registry_manager = IoTHubRegistryManager(connection_str) #print("Conn String: {0}".format(connection_str))