def invoke_method_helper(method):
    direct_method = CloudToDeviceMethod(method_name=method.method_name, payload=method.serialize())
    registry_manager = IoTHubRegistryManager(connection_string)

    payload = registry_manager.invoke_device_module_method(device_id, module_d, direct_method).payload
    if payload is not None and 'error' in payload:
        print(payload['error'])
        return None

    return payload
Exemplo n.º 2
0
class GraphManager:
    def __init__(self, ioThubConnectionString, deviceId, moduleId,
                 operationsApiVersion):
        self._iotHubConnStr = ioThubConnectionString
        self._deviceId = deviceId
        self._moduleId = moduleId
        self._apiVersion = operationsApiVersion

        self._registryManager = IoTHubRegistryManager(self._iotHubConnStr)

    def InvokeModuleMethod(self, methodName, payload):
        moduleMethod = CloudToDeviceMethod(method_name=methodName,
                                           payload=payload)
        return self._registryManager.invoke_device_module_method(
            self._deviceId, self._moduleId, moduleMethod)

    def GraphTopologySet(self, opParams):
        if opParams is None:
            logging.info('Operation parameters missing')
            raise Exception

        if opParams.get('topologyUrl') is not None:
            topologyJsonString = urlToText(opParams['topologyUrl'])
        elif opParams.get('topologyFile') is not None:
            from sys import platform

            if platform == "win32":  #Windows
                fpath = 'file:///' + path.join(
                    pathlib.Path(__file__).parent.absolute(),
                    opParams['topologyFile'])
            else:  #Linux or MacOS
                fpath = 'file://' + path.join(
                    pathlib.Path(__file__).parent.absolute(),
                    opParams['topologyFile'])

            topologyJsonString = urlToText(fpath)
        else:
            logging.info('Neither topologyUrl nor topologyFile specified')

        topologyJson = json.loads(topologyJsonString)

        return self.InvokeModuleMethod('GraphTopologySet', topologyJson)

    def GenericCall(self, methodName, opParams):
        if opParams is None:
            logging.info('Operation parameters missing')
            raise Exception

        opParams['@apiVersion'] = self._apiVersion
        return self.InvokeModuleMethod(methodName, opParams)
class IoTHubHandler:
    def __init__(self, iot_hub_connection_string):
        self.registry_manager = IoTHubRegistryManager(iot_hub_connection_string)

    async def send_message(self, message, device_id, module_id, method_name):
        payload = {"body": json.loads(message.data), "properties": message.custom_properties}
        module_method = CloudToDeviceMethod(
            method_name=method_name,
            payload=payload,
            response_timeout_in_seconds=30)

        print("Invoking message called")
        resp = self.registry_manager.invoke_device_module_method(device_id, module_id, module_method)
        if resp.payload is not None:
            print(json.dumps(resp.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
Exemplo n.º 5
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
Exemplo n.º 6
0
class GraphManager:
    
    def __init__(self):
        config_data = pathlib.Path('appsettings.json').read_text()
        config = json.loads(config_data)

        self.device_id = config['deviceId']
        self.module_id = config['moduleId']

        self.registry_manager = IoTHubRegistryManager(config['IoThubConnectionString'])
        self.rtsp_url = config['rtspUrl']
        self.printColors = { 
            'yellow': '\033[93m {}\033[00m',
            'green': '\033[92m {}\033[00m',
            'red': '\033[91m {}\033[00m'
        }

    def invoke_wait_for_input(self, message):
        print(self.printColors['yellow'].format(message))
        return input()

    """
    Create and invoke the CloudToDeviceMethod to execute a Direct Method on the device.
    """
    def invoke_module_method(self, method):
        # Get the name of the Direct Method
        method_name =  method.method_name
        # Get the payload of the Direct Method
        payload = method.serialize()
        direct_method = CloudToDeviceMethod(method_name=method_name, payload=payload)
        
        print(self.printColors['green'].format("\n-----------------------  Request: %s  --------------------------------------------------\n" % method_name))
        print(json.dumps(payload, indent=4))
        
        # Invoke the Direct Method
        resp = self.registry_manager.invoke_device_module_method(self.device_id, self.module_id, direct_method)
        
        print(self.printColors['green'].format("\n---------------  Response: %s - Status: %s  ---------------\n" % (method_name, resp.status)))

        # Check if the execution was successful and print out the payload (if available)
        if resp.payload is not None and 'error' in resp.payload:
            raise Exception(json.dumps(resp.payload['error'], indent=4))
        elif resp.payload is not None:
            print(json.dumps(resp.payload, indent=4))
    
    def graph_topology_set(self, graph_topology):
        self.invoke_module_method(MediaGraphTopologySetRequest(graph=graph_topology))

    def graph_topology_list(self):
        self.invoke_module_method(MediaGraphTopologyListRequest())

    def graph_topology_get(self, graph_topology_name):
        self.invoke_module_method(MediaGraphTopologyGetRequest(name=graph_topology_name))

    def graph_topology_delete(self, graph_topology_name):
        self.invoke_module_method(MediaGraphTopologyDeleteRequest(name=graph_topology_name))

    def graph_instance_set(self, graph_instance):
        self.invoke_module_method(MediaGraphInstanceSetRequest(instance=graph_instance))

    def graph_instance_list(self):
        self.invoke_module_method(MediaGraphInstanceListRequest())

    def graph_instance_activate(self, graph_instance_name):
        self.invoke_module_method(MediaGraphInstanceActivateRequest(name=graph_instance_name))

    def graph_instance_deactivate(self, graph_instance_name):
        self.invoke_module_method(MediaGraphInstanceDeActivateRequest(name=graph_instance_name))
    
    def graph_instance_delete(self, graph_instance_name):
        self.invoke_module_method(MediaGraphInstanceDeleteRequest(name=graph_instance_name))
    
    """
    Create an instance of a Graph Instance and set the required instance parameters
    """
    def create_graph_instance(self, graph_topology, rtsp_url):
        graph_instance_name = "Sample-Graph-1"
        graph_instance_description = "Sample graph description"
        url_param = MediaGraphParameterDefinition(name="rtspUrl", value=rtsp_url)
        graph_instance_properties = MediaGraphInstanceProperties(description=graph_instance_description, topology_name=graph_topology.name, parameters=[url_param])

        graph_instance = MediaGraphInstance(name=graph_instance_name, properties=graph_instance_properties)

        return graph_instance
Exemplo n.º 7
0
iothub_connection_str = os.getenv("IOTHUB_CONNECTION_STRING")
device_id = os.getenv("IOTHUB_DEVICE_ID")
module_id = os.getenv("IOTHUB_MODULE_ID")
method_name = "lockDoor"
method_payload = "now"

try:
    # RegistryManager
    iothub_registry_manager = IoTHubRegistryManager(iothub_connection_str)

    # Create Module
    primary_key = "aaabbbcccdddeeefffggghhhiiijjjkkklllmmmnnnoo"
    secondary_key = "111222333444555666777888999000aaabbbcccdddee"
    managed_by = ""
    new_module = iothub_registry_manager.create_module_with_sas(
        device_id, module_id, managed_by, primary_key, secondary_key)

    deviceMethod = CloudToDeviceMethod(method_name=method_name,
                                       payload=method_payload)
    iothub_registry_manager.invoke_device_module_method(
        device_id, module_id, deviceMethod)

    # Delete Module
    iothub_registry_manager.delete_module(device_id, module_id)
    print("Deleted Module {0}".format(module_id))

except Exception as ex:
    print("Unexpected error {0}".format(ex))
except KeyboardInterrupt:
    print("IoTHubRegistryManager sample stopped")
Exemplo n.º 8
0
class GraphManager:
    def __init__(self):
        self.registry_manager = IoTHubRegistryManager(IOTHUB_CONNECTION_STRING)
        self.device_id = DEVICE_ID
        self.module_id = MODULE_ID

    def invoke_method2(self, method_name, payload):

        body = {
            "methodName": method_name,
            "responseTimeoutInSeconds": 10,
            "connectTimeoutInSeconds": 10,
            "payload": payload
        }

        url = 'https://main.iothub.ext.azure.com/api/dataPlane/post'
        data = {
            "apiVersion": "2018-06-30",
            "authorizationPolicyKey":
            "rDav1fU61BRTezz8NewMe/UNasZob1rQ8FowPqrbD28=",
            "authorizationPolicyName": "service",
            "hostName": "customvision.azure-devices.net",
            "requestPath": "/twins/testcam/modules/lvaEdge/methods",
            "requestBody": str(body)
        }

        header = {"Authorization": IOTHUB_CONNECTION_STRING}
        res = requests.post(url, headers=header, data=data)
        return res.json()

    def invoke_method(self, method_name, payload):
        mutex.acquire()
        try:
            module_method = CloudToDeviceMethod(method_name=method_name,
                                                payload=payload,
                                                response_timeout_in_seconds=30)
            res = self.registry_manager.invoke_device_module_method(
                self.device_id, self.module_id, module_method)
            mutex.release()
            return res.as_dict()
        except:
            mutex.release()
            print("[ERROR] Failed to invoke direct method:",
                  sys.exc_info(),
                  flush=True)
            return {'error': 'failed to invoke direct method'}

    def invoke_graph_topology_get(self, name):
        method = 'GraphTopologyGet'
        payload = {
            "@apiVersion": "1.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_topology_set(self, name, properties):
        method = 'GraphTopologySet'
        payload = {
            "@apiVersion": "1.0",
            'name': name,
            'properties': properties,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_topology_list(self):
        method = 'GraphTopologyList'
        payload = {
            '@apiVersion': '1.0',
        }
        return self.invoke_method(method, payload)

    def invoke_graph_topology_delete(self, name):
        method = 'GraphTopologyDelete'
        payload = {
            '@apiVersion': '1.0',
            'name': name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_get(self, name):
        method = 'GraphInstanceGet'
        payload = {
            '@apiVersion': '1.0',
            'name': name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_set(self, name, properties):
        method = 'GraphInstanceSet'
        payload = {
            "@apiVersion": "1.0",
            'name': name,
            'properties': properties,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_delete(self, name):
        method = 'GraphInstanceDelete'
        payload = {
            '@apiVersion': '1.0',
            'name': name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_list(self):
        method = 'GraphInstanceList'
        payload = {
            '@apiVersion': '1.0',
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_activate(self, name):
        method = 'GraphInstanceActivate'
        payload = {
            '@apiVersion': '1.0',
            'name': name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_deactivate(self, name):
        method = 'GraphInstanceDeactivate'
        payload = {
            '@apiVersion': '1.0',
            'name': name,
        }
        return self.invoke_method(method, payload)

    # default grpc settings
    def invoke_graph_grpc_topology_set(self):
        method = 'GraphTopologySet'
        with open('grpc_topology.json') as f:
            payload = json.load(f)
        return self.invoke_method(method, payload)

    def invoke_graph_grpc_instance_set(self, name, rtspUrl, frameRate):
        properties = {
            "topologyName":
            "InferencingWithGrpcExtension",
            "description":
            "Sample graph description",
            "parameters": [
                {
                    "name": "rtspUrl",
                    "value": rtspUrl
                },
                {
                    "name": "frameRate",
                    "value": frameRate
                },
                {
                    "name": "grpcExtensionAddress",
                    "value": "tcp://InferenceModule:44000"
                },
                {
                    "name": "frameHeight",
                    "value": "540"
                },
                {
                    "name": "frameWidth",
                    "value": "960"
                },
            ]
        }
        return self.invoke_graph_instance_set(name, properties)
Exemplo n.º 9
0
class GraphManager:
    def __init__(self):
        if is_edge():
            try:
                self.registry_manager = IoTHubRegistryManager(
                    IOTHUB_CONNECTION_STRING)
            except:
                logger.warning(
                    'IoTHub authentication failed. The server will terminate in 10 seconds.')
                time.sleep(10)
                sys.exit(-1)

        else:
            self.registry_manager = None
        self.device_id = DEVICE_ID
        self.module_id = MODULE_ID

    def invoke_method(self, method_name, payload):
        if not self.registry_manager:
            print(
                "[WARNING] Not int edge evironment, ignore direct message", flush=True
            )
        mutex.acquire()
        try:
            module_method = CloudToDeviceMethod(
                method_name=method_name, payload=payload, response_timeout_in_seconds=30
            )
            res = self.registry_manager.invoke_device_module_method(
                self.device_id, self.module_id, module_method
            )
            mutex.release()
            return res.as_dict()
        except:
            mutex.release()
            print("[ERROR] Failed to invoke direct method:",
                  sys.exc_info(), flush=True)
            return {"error": "failed to invoke direct method"}

    def invoke_graph_topology_get(self, name):
        method = "GraphTopologyGet"
        payload = {
            "@apiVersion": "2.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_topology_set(self, name, properties):
        method = "GraphTopologySet"
        payload = {
            "@apiVersion": "2.0",
            "name": name,
            "properties": properties,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_topology_list(self):
        method = "GraphTopologyList"
        payload = {
            "@apiVersion": "2.0",
        }
        return self.invoke_method(method, payload)

    def invoke_graph_topology_delete(self, name):
        method = "GraphTopologyDelete"
        payload = {
            "@apiVersion": "2.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_get(self, name):
        method = "GraphInstanceGet"
        payload = {
            "@apiVersion": "2.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_set(self, name, properties):
        method = "GraphInstanceSet"
        payload = {
            "@apiVersion": "2.0",
            "name": name,
            "properties": properties,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_delete(self, name):
        method = "GraphInstanceDelete"
        payload = {
            "@apiVersion": "2.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_list(self):
        method = "GraphInstanceList"
        payload = {
            "@apiVersion": "2.0",
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_activate(self, name):
        method = "GraphInstanceActivate"
        payload = {
            "@apiVersion": "2.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_deactivate(self, name):
        method = "GraphInstanceDeactivate"
        payload = {
            "@apiVersion": "2.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    # default grpc settings
    def invoke_graph_grpc_topology_set(self):
        method = "GraphTopologySet"
        with open("grpc_topology.json") as f:
            payload = json.load(f)
        return self.invoke_method(method, payload)

    def invoke_graph_grpc_instance_set(self, name, rtspUrl, frameRate, recording_duration):
        recordingDuration = "PT{}S".format(recording_duration)
        find_cred, username, password = self.parse_rtsp_credential(rtspUrl)
        properties = {
            "topologyName": "InferencingWithGrpcExtension",
            "description": "Sample graph description",
            "parameters": [
                {"name": "rtspUrl", "value": rtspUrl},
                {"name": "rtspUserName", "value": username},
                {"name": "rtspPassword", "value": password},
                {"name": "frameRate", "value": frameRate},
                {"name": "instanceId", "value": name},
                {"name": "recordingDuration", "value": recordingDuration},
                {
                    "name": "grpcExtensionAddress",
                    "value": "tcp://*****:*****@' in rtspUrl:
            pattern = '\\:\\/\\/(?P<_0>.+)\\:(?P<_1>.+)\\@'
            out = re.findall(pattern, rtspUrl)
            if len(out) > 0:
                username = out[0][0]
                password = out[0][1]
                find_cred = True

        return(find_cred, username, password)
class GraphManager:
    def __init__(self):
        if is_edge():
            self.registry_manager = IoTHubRegistryManager(
                IOTHUB_CONNECTION_STRING)
        else:
            self.registry_manager = None
        self.device_id = DEVICE_ID
        self.module_id = MODULE_ID

    def invoke_method(self, method_name, payload):
        if not self.registry_manager:
            print("[WARNING] Not int edge evironment, ignore direct message",
                  flush=True)
        mutex.acquire()
        try:
            module_method = CloudToDeviceMethod(method_name=method_name,
                                                payload=payload,
                                                response_timeout_in_seconds=30)
            res = self.registry_manager.invoke_device_module_method(
                self.device_id, self.module_id, module_method)
            mutex.release()
            return res.as_dict()
        except:
            mutex.release()
            print("[ERROR] Failed to invoke direct method:",
                  sys.exc_info(),
                  flush=True)
            return {"error": "failed to invoke direct method"}

    def invoke_graph_topology_get(self, name):
        method = "GraphTopologyGet"
        payload = {
            "@apiVersion": "1.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_topology_set(self, name, properties):
        method = "GraphTopologySet"
        payload = {
            "@apiVersion": "1.0",
            "name": name,
            "properties": properties,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_topology_list(self):
        method = "GraphTopologyList"
        payload = {
            "@apiVersion": "1.0",
        }
        return self.invoke_method(method, payload)

    def invoke_graph_topology_delete(self, name):
        method = "GraphTopologyDelete"
        payload = {
            "@apiVersion": "1.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_get(self, name):
        method = "GraphInstanceGet"
        payload = {
            "@apiVersion": "1.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_set(self, name, properties):
        method = "GraphInstanceSet"
        payload = {
            "@apiVersion": "1.0",
            "name": name,
            "properties": properties,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_delete(self, name):
        method = "GraphInstanceDelete"
        payload = {
            "@apiVersion": "1.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_list(self):
        method = "GraphInstanceList"
        payload = {
            "@apiVersion": "1.0",
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_activate(self, name):
        method = "GraphInstanceActivate"
        payload = {
            "@apiVersion": "1.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    def invoke_graph_instance_deactivate(self, name):
        method = "GraphInstanceDeactivate"
        payload = {
            "@apiVersion": "1.0",
            "name": name,
        }
        return self.invoke_method(method, payload)

    # default grpc settings
    def invoke_graph_grpc_topology_set(self):
        method = "GraphTopologySet"
        with open("grpc_topology.json") as f:
            payload = json.load(f)
        return self.invoke_method(method, payload)

    def invoke_graph_grpc_instance_set(self, name, rtspUrl, frameRate):
        properties = {
            "topologyName":
            "InferencingWithGrpcExtension",
            "description":
            "Sample graph description",
            "parameters": [
                {
                    "name": "rtspUrl",
                    "value": rtspUrl
                },
                {
                    "name": "frameRate",
                    "value": frameRate
                },
                {
                    "name": "instanceId",
                    "value": name
                },
                {
                    "name": "grpcExtensionAddress",
                    "value": "tcp://InferenceModule:44000",
                },
                {
                    "name": "frameHeight",
                    "value": "540"
                },
                {
                    "name": "frameWidth",
                    "value": "960"
                },
            ],
        }
        return self.invoke_graph_instance_set(name, properties)

    # default http extension settings
    def invoke_graph_http_topology_set(self):
        method = "GraphTopologySet"
        with open("http_topology.json") as f:
            payload = json.load(f)
        return self.invoke_method(method, payload)

    def invoke_graph_http_instance_set(self, name, rtspUrl, frameRate):
        inferencingUrl = "http://InferenceModule:5000/predict?camera_id=" + str(
            name)
        properties = {
            "topologyName":
            "InferencingWithHttpExtension",
            "description":
            "Sample graph description",
            "parameters": [
                {
                    "name": "rtspUrl",
                    "value": rtspUrl
                },
                {
                    "name": "frameRate",
                    "value": frameRate
                },
                {
                    "name": "inferencingUrl",
                    "value": inferencingUrl
                },
                {
                    "name": "frameHeight",
                    "value": "540"
                },
                {
                    "name": "frameWidth",
                    "value": "960"
                },
            ],
        }
        return self.invoke_graph_instance_set(name, properties)

    def invoke_topology_set(self, mode):
        if mode == "grpc":
            return self.invoke_graph_grpc_topology_set()
        elif mode == "http":
            return self.invoke_graph_http_topology_set()
        else:
            return "LVA mode error"

    def invoke_instance_set(self, mode, name, rtspUrl, frameRate):
        if mode == "grpc":
            return self.invoke_graph_grpc_instance_set(name, rtspUrl,
                                                       frameRate)
        elif mode == "http":
            return self.invoke_graph_http_instance_set(name, rtspUrl,
                                                       frameRate)
        else:
            return "LVA mode error"
Exemplo n.º 11
0
class GraphManager:
    def __init__(self):
        self.device_id = getenv(constants.device_id)
        self.device_tag = getenv(constants.device_tag)
        self.tag_value = getenv(constants.tag_value)
        self.module_id = getenv(constants.module_id)
        self.api_version = constants.topology_api_version

        self.registry_manager = IoTHubRegistryManager(getenv(constants.iot_connection_string))

        if self.device_id is None:
            self.device_list = self.get_device_list()

    def get_device_list(self):
        query_string = f"SELECT * FROM devices WHERE tags.{self.device_tag} = '{self.tag_value}'"
        query_spec = QuerySpecification(query=query_string)
        response = self.registry_manager.query_iot_hub(query_spec, None, None)
        return response.items

    def invoke(self, method_name, payload):
        if method_name == 'GraphTopologySet':
            self.graph_topology_set(payload)
            return

        if method_name == 'WaitForInput':
            print(payload['message'])
            input()
            return

        self.invoke_module_method(method_name, payload)

    def invoke_module_method(self, method_name, payload):
        # make sure '@apiVersion' has been set
        payload['@apiVersion'] = self.api_version

        module_method = CloudToDeviceMethod(
            method_name=method_name,
            payload=payload,
            response_timeout_in_seconds=30)

        device_id = self.device_id
        try:
            if device_id is None:
                for device in self.device_list:
                    device_id = device.device_id
                    self.invoke_device_module_method(device_id, method_name, module_method, payload)
            else:
                self.invoke_device_module_method(device_id, method_name, module_method, payload)

        except Exception as ex:
            if ex.response.status_code == 404:
                print(">>>>>>>>>> Warning: device '%s' does not have the '%s' module deployed, or the module has not yet initalized <<<<<<<<<<" %
                      (device_id, self.module_id))

    def invoke_device_module_method(self, device_id, method_name, module_method, payload):
        print("\n----------------------- Device: %s - Request: %s  --------------------------------------------------\n" % (device_id, method_name))
        print(json.dumps(payload, indent=4))

        resp = self.registry_manager.invoke_device_module_method(device_id, self.module_id, module_method)

        print("\n----------------------- Device: %s - Response: %s - Status: %s  ------------------------------------\n" %
              (device_id, method_name, resp.status))

        if resp.payload is not None:
            print(json.dumps(resp.payload, indent=4))

    def graph_topology_set(self, op_parameters):
        if op_parameters is None:
            raise Exception('Operation parameters missing')

        if op_parameters.get('topologyUrl') is not None:
            topology_json = read_url(op_parameters['topologyUrl'])
        elif op_parameters.get('topologyFile') is not None:
            topology_path = Path(__file__).parent.joinpath(op_parameters['topologyFile'])
            topology_json = topology_path.read_text()
        else:
            raise Exception('Neither topologyUrl nor topologyFile is specified')

        topology = json.loads(topology_json)

        self.invoke_module_method('GraphTopologySet', topology)