Exemple #1
0
def create_entities() -> List[ContextEntity]:
    """
    Create entities with random values
    Returns:

    """
    def create_attr():
        return {
            'temperature': {
                'value': random(),
                'type': 'Number'
            },
            'humidity': {
                'value': random(),
                'type': 'Number'
            },
            'co2': {
                'value': random(),
                'type': 'Number'
            }
        }

    return [
        ContextEntity(id='Kitchen', type='Room', **create_attr()),
        ContextEntity(id='LivingRoom', type='Room', **create_attr())
    ]
Exemple #2
0
    def load(self, json_string: str, semantic_manager: 'SemanticsManager'):
        """
        Load the state of the registry out of a json string. The current
        state will be discarded

        Args:
            json_string (str): State expressed as json string
            semantic_manager (SemanticsManager): manager to which registry
                belongs
        Returns:
             None
        """
        self.clear()

        save = json.loads(json_string)
        for instance_dict in save['instances']:
            entity_json = instance_dict['entity']
            header = InstanceHeader.parse_raw(instance_dict['header'])

            context_entity = ContextEntity.parse_raw(entity_json)

            instance = semantic_manager._context_entity_to_semantic_class(
                context_entity, header)

            if instance_dict['old_state'] is not None:
                instance.old_state.state = \
                    ContextEntity.parse_raw(instance_dict['old_state'])

            self._registry[instance.get_identifier()] = instance

        for identifier in save['deleted_identifiers']:
            self._deleted_identifiers.append(
                InstanceIdentifier.parse_raw(identifier))
Exemple #3
0
        def build_context_entity_from_device(device: Device) -> ContextEntity:
            from filip.models.base import DataType
            entity = ContextEntity(id=device.entity_name,
                                   type=device.entity_type)

            for command in device.commands:
                entity.add_attributes([
                    # Command attribute will be registered by the device_update
                    NamedContextAttribute(name=f"{command.name}_info",
                                          type=DataType.COMMAND_RESULT),
                    NamedContextAttribute(name=f"{command.name}_status",
                                          type=DataType.COMMAND_STATUS)
                ])
            for attribute in device.attributes:
                entity.add_attributes([
                    NamedContextAttribute(name=attribute.name,
                                          type=DataType.STRUCTUREDVALUE,
                                          metadata=attribute.metadata)
                ])
            for static_attribute in device.static_attributes:
                entity.add_attributes([
                    NamedContextAttribute(name=static_attribute.name,
                                          type=static_attribute.type,
                                          value=static_attribute.value,
                                          metadata=static_attribute.metadata)
                ])
            return entity
Exemple #4
0
    def test_entity_filtering(self):
        """
        Test filter operations of context broker client
        """
        with ContextBrokerClient(
                url=settings.CB_URL,
                fiware_header=self.fiware_header) as client:
            # test patterns
            with self.assertRaises(ValueError):
                client.get_entity_list(id_pattern='(&()?')
            with self.assertRaises(ValueError):
                client.get_entity_list(type_pattern='(&()?')
            entities_a = [ContextEntity(id=str(i),
                                        type=f'filip:object:TypeA') for i in
                          range(0, 5)]

            client.update(action_type=ActionType.APPEND, entities=entities_a)
            entities_b = [ContextEntity(id=str(i),
                                        type=f'filip:object:TypeB') for i in
                          range(6, 10)]

            client.update(action_type=ActionType.APPEND, entities=entities_b)

            entities_all = client.get_entity_list()
            entities_by_id_pattern = client.get_entity_list(
                id_pattern='.*[1-5]')
            self.assertLess(len(entities_by_id_pattern), len(entities_all))

            entities_by_type_pattern = client.get_entity_list(
                type_pattern=".*TypeA$")
            self.assertLess(len(entities_by_type_pattern), len(entities_all))

            qs = QueryString(qs=[('presentValue', '>', 0)])
            entities_by_query = client.get_entity_list(q=qs)
            self.assertLess(len(entities_by_query), len(entities_all))

            # test options
            for opt in list(AttrsFormat):
                entities_by_option = client.get_entity_list(response_format=opt)
                self.assertEqual(len(entities_by_option), len(entities_all))
                self.assertEqual(client.get_entity(
                    entity_id='0',
                    response_format=opt),
                    entities_by_option[0])
            with self.assertRaises(ValueError):
                client.get_entity_list(response_format='not in AttrFormat')

            client.update(action_type=ActionType.DELETE, entities=entities_a)

            client.update(action_type=ActionType.DELETE, entities=entities_b)
Exemple #5
0
    def setUp(self) -> None:
        """
        Setup test data
        Returns:
            None
        """
        self.fiware_header = FiwareHeader(
            service=settings.FIWARE_SERVICE,
            service_path=settings.FIWARE_SERVICEPATH)
        clear_all(fiware_header=self.fiware_header,
                  cb_url=settings.CB_URL,
                  iota_url=settings.IOTA_JSON_URL)
        self.resources = {
            "entities_url": "/v2/entities",
            "types_url": "/v2/types",
            "subscriptions_url": "/v2/subscriptions",
            "registrations_url": "/v2/registrations"
        }
        self.attr = {'temperature': {'value': 20.0,
                                     'type': 'Number'}}
        self.entity = ContextEntity(id='MyId', type='MyType', **self.attr)


        self.client = ContextBrokerClient(
            url=settings.CB_URL,
            fiware_header=self.fiware_header)
        self.subscription = Subscription.parse_obj({
            "description": "One subscription to rule them all",
            "subject": {
                "entities": [
                    {
                        "idPattern": ".*",
                        "type": "Room"
                    }
                ],
                "condition": {
                    "attrs": [
                        "temperature"
                    ],
                    "expression": {
                        "q": "temperature>40"
                    }
                }
            },
            "notification": {
                "http": {
                    "url": "http://localhost:1234"
                },
                "attrs": [
                    "temperature",
                    "humidity"
                ]
            },
            "expires": datetime.now(),
            "throttling": 0
        })
Exemple #6
0
 def test_pagination(self):
     """
     Test pagination of context broker client
     Test pagination. only works if enough entities are available
     """
     with ContextBrokerClient(
             url=settings.CB_URL,
             fiware_header=self.fiware_header) as client:
         entities_a = [ContextEntity(id=str(i),
                                     type=f'filip:object:TypeA') for i in
                       range(0, 1000)]
         client.update(action_type=ActionType.APPEND, entities=entities_a)
         entities_b = [ContextEntity(id=str(i),
                                     type=f'filip:object:TypeB') for i in
                       range(1000, 2001)]
         client.update(action_type=ActionType.APPEND, entities=entities_b)
         self.assertLessEqual(len(client.get_entity_list(limit=1)), 1)
         self.assertLessEqual(len(client.get_entity_list(limit=999)), 999)
         self.assertLessEqual(len(client.get_entity_list(limit=1001)), 1001)
         self.assertLessEqual(len(client.get_entity_list(limit=2001)), 2001)
 def create_entity(self):
     """Creates entitiy of PID controller in orion context broker"""
     try:
         self.ORION_CB.get_entity(entity_id=self.params['controller_name'],
                                  entity_type=self.params['type'])
         print('Entity name already assigned')
     except requests.exceptions.HTTPError as err:
         msg = err.args[0]
         if "NOT FOUND" not in msg.upper():
             raise  # throw other errors except "entity not found"
         print('[INFO]: Create new PID entity')
         pid_entity = ContextEntity(id=f"{self.params['controller_name']}",
                                    type=self.params['type'])
         cb_attrs = []
         for attr in ['Kp', 'Ki', 'Kd', 'lim_low', 'lim_upper', 'setpoint']:
             cb_attrs.append(
                 NamedContextAttribute(name=attr,
                                       type="Number",
                                       value=self.params[attr]))
         pid_entity.add_attributes(attrs=cb_attrs)
         self.ORION_CB.post_entity(entity=pid_entity, update=True)
Exemple #8
0
 def test_batch_operations(self):
     """
     Test batch operations of context broker client
     """
     with ContextBrokerClient(
             url=settings.CB_URL,
             fiware_header=self.fiware_header) as client:
         entities = [ContextEntity(id=str(i),
                                   type=f'filip:object:TypeA') for i in
                     range(0, 1000)]
         client.update(entities=entities, action_type=ActionType.APPEND)
         entities = [ContextEntity(id=str(i),
                                   type=f'filip:object:TypeB') for i in
                     range(0, 1000)]
         client.update(entities=entities, action_type=ActionType.APPEND)
         entity = EntityPattern(idPattern=".*", typePattern=".*TypeA$")
         query = Query.parse_obj(
             {"entities": [entity.dict(exclude_unset=True)]})
         self.assertEqual(1000,
                          len(client.query(query=query,
                                           response_format='keyValues')))
Exemple #9
0
 def test_fiware_header(self):
     """
     Test for fiware header
     """
     header = FiwareHeader.parse_obj(self.fiware_header)
     self.assertEqual(header.dict(by_alias=True), self.fiware_header)
     self.assertEqual(header.json(by_alias=True),
                      json.dumps(self.fiware_header))
     self.assertRaises(ValidationError,
                       FiwareHeader,
                       service='jkgsadh ',
                       service_path='/testing')
     self.assertRaises(ValidationError,
                       FiwareHeader,
                       service='%',
                       service_path='/testing')
     self.assertRaises(ValidationError,
                       FiwareHeader,
                       service='filip',
                       service_path='testing/')
     self.assertRaises(ValidationError,
                       FiwareHeader,
                       service='filip',
                       service_path='/$testing')
     self.assertRaises(ValidationError,
                       FiwareHeader,
                       service='filip',
                       service_path='/testing ')
     self.assertRaises(ValidationError,
                       FiwareHeader,
                       service='filip',
                       service_path='#')
     headers = FiwareHeader.parse_obj(self.fiware_header)
     with ContextBrokerClient(url=settings.CB_URL,
                              fiware_header=headers) as client:
         entity = ContextEntity(id='myId', type='MyType')
         for path in self.service_paths:
             client.fiware_service_path = path
             client.post_entity(entity=entity)
             client.get_entity(entity_id=entity.id)
         client.fiware_service_path = '/#'
         self.assertGreaterEqual(len(client.get_entity_list()),
                                 len(self.service_paths))
         for path in self.service_paths:
             client.fiware_service_path = path
             client.delete_entity(entity_id=entity.id,
                                  entity_type=entity.type)
Exemple #10
0
                        def test(dictionary: Dict):
                            # either the assignment throws an error or
                            # the entity can get posted and gets found

                            assignment_error = False
                            try:
                                entity = ContextEntity(**dictionary)
                            except:
                                assignment_error = True
                                self.assertFalse(needs_to_succeed)

                            if not assignment_error:
                                client.post_entity(entity=entity)
                                # if post successful get will not throw an
                                # error
                                client.get_entity(entity_id=entity.id,
                                                  entity_type=entity.type)
                                client.delete_entity(entity_id=entity.id,
                                                     entity_type=entity.type)
Exemple #11
0
                          "type": "Store",
                          "id": "urn:ngsi-ld:Store:002",
                          "address": {
                              "type": "Text",
                              "value": "Friedrichstraße 44"
                          },
                          "location": {
                              "type": "Text",
                              "value": "[13.3903, 52.5075]"
                          },
                          "name": {
                              "type": "Text",
                              "value": "Checkpoint Markt"
                          }
                      }]
        store_entities = [ContextEntity(**store) for store in store_dict]
        for entity in store_entities:
            cb_client.post_entity(entity)

    # ## 1.2 Product entities
    #
    with ContextBrokerClient(fiware_header=fiware_header) as cb_client:
        product_dict = [
            {
                "id": "urn:ngsi-ld:Product:001", "type": "Product",
                "name": {
                    "type": "Text", "value": "Beer"
                },
                "size": {
                    "type": "Text", "value": "S"
                },
Exemple #12
0
    fiware_header = FiwareHeader(service=SERVICE, service_path=SERVICE_PATH)
    cb_client = ContextBrokerClient(url=CB_URL, fiware_header=fiware_header)

    room_001 = {
        "id": "urn:ngsi-ld:Room:001",
        "type": "Room",
        "temperature": {
            "value": 11,
            "type": "Float"
        },
        "pressure": {
            "value": 111,
            "type": "Integer"
        }
    }
    room_entity = ContextEntity(**room_001)
    cb_client.post_entity(entity=room_entity)

    # # 2 Setup a subscription and MQTT notifications
    #
    # Create the data for the subscription. Have a look at the condition and
    # the attribute section. Only a change of the temperature attribute will
    # trigger the subscription and only temperature data will be included
    # into the message.
    # Additionally, you should be aware of the throttling and expiration of a
    # subscription.
    #
    # For more details on subscription you might want to
    # check the Subscription model or the official tutorials.
    sub_example = {
        "description": "Subscription to receive MQTT-Notifications about "
Exemple #13
0
    def test_patch_entity(self) -> None:
        """
        Test the methode: patch_entity
        Returns:
           None
        """

        # setup test-entity
        entity = ContextEntity(id="test_id1", type="test_type1")
        attr1 = NamedContextAttribute(name="attr1", value="1")
        attr1.metadata["m1"] = \
            NamedMetadata(name="meta1", type="metatype", value="2")
        attr2 = NamedContextAttribute(name="attr2", value="2")
        attr1.metadata["m2"] = \
            NamedMetadata(name="meta2", type="metatype", value="3")
        entity.add_attributes([attr1, attr2])

        # sub-Test1: Post new
        self.client.patch_entity(entity=entity)
        self.assertEqual(entity,
                         self.client.get_entity(entity_id=entity.id))
        self.tearDown()

        # sub-Test2: ID/type of old_entity changed
        self.client.post_entity(entity=entity)
        test_entity = ContextEntity(id="newID", type="newType")
        test_entity.add_attributes([attr1, attr2])
        self.client.patch_entity(test_entity, old_entity=entity)
        self.assertEqual(test_entity,
                         self.client.get_entity(entity_id=test_entity.id))
        self.assertRaises(RequestException, self.client.get_entity,
                          entity_id=entity.id)
        self.tearDown()

        # sub-Test3: a non valid old_entity is provided, entity exists
        self.client.post_entity(entity=entity)
        old_entity = ContextEntity(id="newID", type="newType")

        self.client.patch_entity(entity, old_entity=old_entity)
        self.assertEqual(entity, self.client.get_entity(entity_id=entity.id))
        self.tearDown()

        # sub-Test4: no old_entity provided, entity is new
        old_entity = ContextEntity(id="newID", type="newType")
        self.client.patch_entity(entity, old_entity=old_entity)
        self.assertEqual(entity, self.client.get_entity(entity_id=entity.id))
        self.tearDown()

        # sub-Test5: no old_entity provided, entity is new
        old_entity = ContextEntity(id="newID", type="newType")
        self.client.patch_entity(entity, old_entity=old_entity)
        self.assertEqual(entity, self.client.get_entity(entity_id=entity.id))
        self.tearDown()

        # sub-Test6: New attr, attr del, and attr changed. No Old_entity given
        self.client.post_entity(entity=entity)
        test_entity = ContextEntity(id="test_id1", type="test_type1")
        attr1_changed = NamedContextAttribute(name="attr1", value="2")
        attr1_changed.metadata["m4"] = \
            NamedMetadata(name="meta3", type="metatype5", value="4")
        attr3 = NamedContextAttribute(name="attr3", value="3")
        test_entity.add_attributes([attr1_changed, attr3])
        self.client.patch_entity(test_entity)

        self.assertEqual(test_entity,
                         self.client.get_entity(entity_id=entity.id))
        self.tearDown()

        # sub-Test7: Attr changes, concurrent changes in Fiware,
        #            old_entity given

        self.client.post_entity(entity=entity)

        concurrent_entity = ContextEntity(id="test_id1", type="test_type1")
        attr1_changed = copy.deepcopy(attr1)
        attr1_changed.metadata["m1"].value = "3"
        attr1_changed.value = "4"
        concurrent_entity.add_attributes([attr1_changed, attr2])
        self.client.patch_entity(concurrent_entity)

        user_entity = copy.deepcopy(entity)
        attr3 = NamedContextAttribute(name="attr3", value="3")
        user_entity.add_attributes([attr3])
        self.client.patch_entity(user_entity, old_entity=entity)

        result_entity = concurrent_entity
        result_entity.add_attributes([attr2, attr3])

        self.assertEqual(result_entity,
                         self.client.get_entity(entity_id=entity.id))
        self.tearDown()
Exemple #14
0
    def test_mqtt_subscriptions(self):
        mqtt_url = settings.MQTT_BROKER_URL
        mqtt_topic = ''.join([settings.FIWARE_SERVICE,
                              settings.FIWARE_SERVICEPATH])
        notification = self.subscription.notification.copy(
            update={'http': None, 'mqtt': Mqtt(url=mqtt_url,
                                               topic=mqtt_topic)})
        subscription = self.subscription.copy(
            update={'notification': notification,
                    'description': 'MQTT test subscription',
                    'expires': None})
        entity = ContextEntity(id='myID', type='Room', **self.attr)

        self.client.post_entity(entity=entity)
        sub_id = self.client.post_subscription(subscription)

        sub_message = None

        def on_connect(client, userdata, flags, reasonCode, properties=None):
            if reasonCode != 0:
                logger.error(f"Connection failed with error code: "
                             f"'{reasonCode}'")
                raise ConnectionError
            else:
                logger.info("Successfully, connected with result code " + str(
                    reasonCode))
            client.subscribe(mqtt_topic)

        def on_subscribe(client, userdata, mid, granted_qos, properties=None):
            logger.info("Successfully subscribed to with QoS: %s", granted_qos)

        def on_message(client, userdata, msg):
            logger.info(msg.topic + " " + str(msg.payload))
            nonlocal sub_message
            sub_message = Message.parse_raw(msg.payload)

        def on_disconnect(client, userdata, reasonCode, properties=None):
            logger.info("MQTT client disconnected with reasonCode "
                        + str(reasonCode))

        import paho.mqtt.client as mqtt
        mqtt_client = mqtt.Client(userdata=None,
                                  protocol=mqtt.MQTTv5,
                                  transport="tcp")
        # add our callbacks to the client
        mqtt_client.on_connect = on_connect
        mqtt_client.on_subscribe = on_subscribe
        mqtt_client.on_message = on_message
        mqtt_client.on_disconnect = on_disconnect

        # connect to the server
        mqtt_url = urlparse(mqtt_url)
        mqtt_client.connect(host=mqtt_url.hostname,
                            port=mqtt_url.port,
                            keepalive=60,
                            bind_address="",
                            bind_port=0,
                            clean_start=mqtt.MQTT_CLEAN_START_FIRST_ONLY,
                            properties=None)

        # create a non-blocking thread for mqtt communication
        mqtt_client.loop_start()
        new_value = 50

        self.client.update_attribute_value(entity_id=entity.id,
                                           attr_name='temperature',
                                           value=new_value,
                                           entity_type=entity.type)
        time.sleep(5)

        # test if the subscriptions arrives and the content aligns with updates
        self.assertIsNotNone(sub_message)
        self.assertEqual(sub_id, sub_message.subscriptionId)
        self.assertEqual(new_value, sub_message.data[0].temperature.value)
        mqtt_client.loop_stop()
        mqtt_client.disconnect()
        time.sleep(1)
    # # 1 Creating models
    #
    # Create a building with a weather station as context provider
    # We start from the meta data here. The other way round is also possible but
    # using the api of the Context Entity Model

    # Create unit metadata for the temperature sensor of the weather station
    temperature_metadata = NamedMetadata(name="unit",
                                         value=Unit(name="degree Celsius").dict())
    # create the temperature attribute of the weather station
    temperature = ContextAttribute(type="Number",
                                   value=20.5,
                                   metadata=temperature_metadata)
    # create the complete model of the building with the weather station
    weather_station = ContextEntity(id="urn:ngsi-ld:WeatherStation:001",
                                    type="WeatherStation",
                                    temperature=temperature)

    # print complete weather station object
    print("+"*80)
    print("Building with weather station with one property from a sensor")
    print("+"*80)
    print(weather_station.json(indent=2))

    # create additional properties of the weather station
    windspeed_metadata = NamedMetadata(name="unit",
                                       type="Unit",
                                       value=Unit(name="kilometre per "
                                                              "hour").dict())
    # create the temperature attribute of the weather station
    windspeed = ContextAttribute(type="Number",
    # ## 2 Interact with QL
    #
    # ### 2.1 Create a ContextEntity to work with
    #
    # for more details see: e01_ngsi_v2_context_basics.py
    hall = {
        "id": "Hall_1",
        "type": "Room",
        "temperature": {
            "value": random.randint(0, 100),
            "type": "Integer"
        },
    }

    hall_entity = ContextEntity(**hall)
    cb_client.post_entity(hall_entity)

    # ### 2.2 Manage subscriptions
    #
    # create a subscription
    # Note: that the IP must be the ones that orion and quantumleap can access,
    # e.g. service name or static IP, localhost will not work here.
    ql_client.post_subscription(entity_id=hall_entity.id,
                                cb_url="http://orion:1026",
                                ql_url="http://quantumleap:8668",
                                throttling=0)

    # Get all subscriptions
    subscription_list = cb_client.get_subscription_list()
    #
    # ### 2.1.1 Passing a dict:
    #
    room1 = {
        "id": "Room1",
        "type": "Room",
        "temperature": {
            "value": 11,
            "type": "Float"
        },
        "pressure": {
            "value": 111,
            "type": "Integer"
        }
    }
    room1_entity = ContextEntity(**room1)

    # ### 2.1.2 Using the constructor and interfaces
    #
    room2_entity = ContextEntity(id="Room2", type="Room")
    temp_attr = NamedContextAttribute(name="temperature",
                                      value=22,
                                      type=DataType.FLOAT)
    pressure_attr = NamedContextAttribute(name="pressure",
                                          value=222,
                                          type="Integer")
    room2_entity.add_attributes([temp_attr, pressure_attr])

    # ## 2.2 Post Entities
    #
    print(cb_client.get_entity_list())
Exemple #18
0
SERVICE_PATH = '/<your_path>'

# ToDo: Path to json-files to store entity data for follow up exercises,
#  e.g. ./e3_my_entities.json
WRITE_ENTITIES_FILEPATH = Path("")

# ## Main script
if __name__ == '__main__':
    # create a fiware header object
    fiware_header = FiwareHeader(service=SERVICE, service_path=SERVICE_PATH)
    # clear the state of your service and scope
    clear_context_broker(url=CB_URL, fiware_header=fiware_header)

    # Create a context entity for a `building` following the smart data models
    # specifications
    building = ContextEntity(id="urn:ngsi-ld:building:001", type="Building")

    # create the property `category` to your building
    category = NamedContextAttribute(name="category",
                                     type="Array",
                                     value=["office"])

    # ToDo: create a property `address` for your building. Follow the full yaml
    #  description in the specifications. It reuses the specification from
    #  here: https://schema.org/PostalAddress
    address = NamedContextAttribute(name="address",
                                    type="PostalAddress",
                                    value={...})

    # ToDo: create a `description` property for your building
    building_description = NamedContextAttribute(...)
Exemple #19
0
    def _context_entity_to_semantic_class(
            self, entity: ContextEntity,
            header: InstanceHeader) -> SemanticClass:
        """Converts a ContextEntity to a SemanticClass

        Args:
            entity (ContextEntity): entity to convert
            header (InstanceHeader): Header of the new instance

        Returns:
            SemanticClass or SemanticDeviceClass
        """

        class_name = entity.type

        class_: Type = self.get_class_by_name(class_name)

        if not self.is_class_name_an_device_class(class_name):

            loaded_class: SemanticClass = class_(id=entity.id,
                                                 header=header,
                                                 enforce_new=True)
        else:
            loaded_class: SemanticDeviceClass = class_(id=entity.id,
                                                       header=header,
                                                       enforce_new=True)

        loaded_class.old_state.state = entity

        # load values of class from the context_entity into the instance
        for field in loaded_class.get_fields():
            field.clear()  # remove default values, from hasValue relations
            field_name = field.name
            entity_attribute = entity.get_attribute(field_name)
            if entity_attribute is None:
                raise Exception(
                    f"The corresponding entity for ({entity.id},{entity.type}) "
                    f"in Fiware misses a field that "
                    f"is required by the class_model: {field_name}. The "
                    f"fiware state and the used vocabulary models are not "
                    f"compatible")

            entity_field_value = entity.get_attribute(field_name).value

            if isinstance(entity_field_value, List):
                values = entity_field_value
            else:
                values = [entity_field_value]

            for value in values:
                converted_value = self._convert_value_fitting_for_field(
                    field, value)
                if isinstance(field, RelationField):
                    # we need to bypass the main setter, as it expects an
                    # instance and we do not want to load the instance if it
                    # is not used
                    field._set.add(converted_value)
                else:
                    field.add(converted_value)

        # load references into instance
        references_attribute = entity.get_attribute("referencedBy")
        references = references_attribute.value

        for identifier_str, prop_list in references.items():
            for prop in prop_list:
                loaded_class.add_reference(
                    InstanceIdentifier.parse_raw(
                        identifier_str.replace("---", ".")), prop)

        # load metadata
        metadata_dict = entity.get_attribute("metadata").value
        loaded_class.metadata.name = metadata_dict['name']
        loaded_class.metadata.comment = metadata_dict['comment']

        # load device_settings into instance, if instance is a device
        if isinstance(loaded_class, SemanticDeviceClass):
            settings_attribute = entity.get_attribute("deviceSettings")
            device_settings = DeviceSettings.parse_obj(
                settings_attribute.value)

            for key, value in device_settings.dict().items():
                loaded_class.device_settings.__setattr__(key, value)

        return loaded_class