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")
Ejemplo n.º 2
0
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")
Ejemplo n.º 3
0
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" )
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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
Ejemplo n.º 7
0
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")
Ejemplo n.º 10
0
                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))