smia 0.2.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- smia/__init__.py +106 -0
- smia/aas_model/__init__.py +2 -0
- smia/aas_model/aas_model_utils.py +195 -0
- smia/aas_model/extended_aas.py +54 -0
- smia/aas_model/extended_aas_model.py +531 -0
- smia/aas_model/extended_base.py +115 -0
- smia/aas_model/extended_concept_description.py +19 -0
- smia/aas_model/extended_submodel.py +580 -0
- smia/agents/__init__.py +3 -0
- smia/agents/extensible_smia_agent.py +109 -0
- smia/agents/smia_agent.py +220 -0
- smia/agents/smia_app_agent.py +39 -0
- smia/agents/smia_resource_agent.py +43 -0
- smia/assetconnection/__init__.py +1 -0
- smia/assetconnection/asset_connection.py +369 -0
- smia/assetconnection/http_asset_connection.py +259 -0
- smia/behaviours/__init__.py +3 -0
- smia/behaviours/aas_fsm_behaviour.py +19 -0
- smia/behaviours/acl_handling_behaviour.py +114 -0
- smia/behaviours/check_physical_asset_behaviour.py +33 -0
- smia/behaviours/end_behaviour.py +32 -0
- smia/behaviours/idle_behaviour.py +34 -0
- smia/behaviours/init_aas_archive_behaviour.py +41 -0
- smia/behaviours/init_aas_model_behaviour.py +425 -0
- smia/behaviours/negotiating_behaviour.py +212 -0
- smia/behaviours/specific_handle_behaviours/__init__.py +4 -0
- smia/behaviours/specific_handle_behaviours/handle_capability_behaviour.py +469 -0
- smia/behaviours/specific_handle_behaviours/handle_negotiation_behaviour.py +257 -0
- smia/behaviours/specific_handle_behaviours/handle_svc_request_behaviour.py +265 -0
- smia/behaviours/specific_handle_behaviours/handle_svc_response_behaviour.py +128 -0
- smia/css_ontology/__init__.py +2 -0
- smia/css_ontology/capability_skill_module.py +353 -0
- smia/css_ontology/capability_skill_ontology.py +189 -0
- smia/css_ontology/css_ontology_utils.py +277 -0
- smia/launchers/__init__.py +3 -0
- smia/launchers/smia_cli_starter.py +66 -0
- smia/launchers/smia_docker_starter.py +37 -0
- smia/launchers/smia_starter.py +49 -0
- smia/logic/__init__.py +3 -0
- smia/logic/agent_services.py +106 -0
- smia/logic/exceptions.py +213 -0
- smia/logic/inter_aas_interactions_utils.py +96 -0
- smia/logic/negotiation_utils.py +202 -0
- smia/logic/services_utils.py +105 -0
- smia/states/__init__.py +3 -0
- smia/states/state_booting.py +49 -0
- smia/states/state_booting_resource.py +34 -0
- smia/states/state_idle.py +25 -0
- smia/states/state_running.py +85 -0
- smia/states/state_stopping.py +27 -0
- smia/utilities/__init__.py +6 -0
- smia/utilities/aas_model_extension_utils.py +63 -0
- smia/utilities/fipa_acl_info.py +101 -0
- smia/utilities/general_utils.py +307 -0
- smia/utilities/properties_file_utils.py +240 -0
- smia/utilities/smia_archive_utils.py +393 -0
- smia/utilities/smia_general_info.py +61 -0
- smia/utilities/smia_info.py +85 -0
- smia-0.2.2.dist-info/LICENSE +674 -0
- smia-0.2.2.dist-info/METADATA +209 -0
- smia-0.2.2.dist-info/RECORD +63 -0
- smia-0.2.2.dist-info/WHEEL +5 -0
- smia-0.2.2.dist-info/top_level.txt +1 -0
smia/__init__.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This is the main package of SMIA, that includes all source code and all subpackages.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
__author__ = """Ekaitz Hurtado"""
|
|
6
|
+
__email__ = "ekaitz.hurtado@ehu.eus"
|
|
7
|
+
__version__ = '0.2.1'
|
|
8
|
+
|
|
9
|
+
__all__ = ['launchers', 'agents', 'utilities', 'assetconnection']
|
|
10
|
+
|
|
11
|
+
import logging
|
|
12
|
+
import ntpath
|
|
13
|
+
|
|
14
|
+
import spade
|
|
15
|
+
|
|
16
|
+
from .aas_model.aas_model_utils import AASModelUtils
|
|
17
|
+
from .logic.exceptions import CriticalError
|
|
18
|
+
from .utilities.aas_model_extension_utils import AASModelExtensionUtils
|
|
19
|
+
from .utilities import properties_file_utils, smia_archive_utils
|
|
20
|
+
from .utilities.general_utils import GeneralUtils
|
|
21
|
+
from .utilities.smia_general_info import SMIAGeneralInfo
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def initial_self_configuration():
|
|
25
|
+
"""
|
|
26
|
+
This method executes the initial configuration of the SMIA software.
|
|
27
|
+
"""
|
|
28
|
+
# First, the BaSyx Python SDK is extended to have all new methods available
|
|
29
|
+
AASModelExtensionUtils.extend_basyx_aas_model()
|
|
30
|
+
|
|
31
|
+
# Initialize SMIA archive
|
|
32
|
+
smia_archive_utils.initialize_smia_archive()
|
|
33
|
+
|
|
34
|
+
# Configure logging
|
|
35
|
+
GeneralUtils.configure_logging()
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def run(agent_object):
|
|
39
|
+
"""
|
|
40
|
+
This method runs the SMIA software with a given agent.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
_logger = logging.getLogger(__name__)
|
|
44
|
+
|
|
45
|
+
if agent_object is None:
|
|
46
|
+
_logger.error('To launch SMIA, an agent must be passed to the method "smia.run".')
|
|
47
|
+
return
|
|
48
|
+
|
|
49
|
+
async def main():
|
|
50
|
+
await agent_object.start()
|
|
51
|
+
|
|
52
|
+
await spade.wait_until_finished(agent_object)
|
|
53
|
+
|
|
54
|
+
# In the general properties file you can select the web interface (provided by SPADE).
|
|
55
|
+
web_ui = properties_file_utils.get_dt_general_property('web-ui')
|
|
56
|
+
if web_ui.lower() in ('yes', 'true', 't', '1'):
|
|
57
|
+
# bool(string) cannot be used as it is true as long as the string is not empty.
|
|
58
|
+
agent_object.web.start(hostname="0.0.0.0", port="10002")
|
|
59
|
+
|
|
60
|
+
spade.run(main())
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def load_aas_model(file_path):
|
|
64
|
+
"""
|
|
65
|
+
This method loads the AAS model using a given path to the AASX package file.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
file_path (str): path to the AASX package file.
|
|
69
|
+
"""
|
|
70
|
+
# If the user has not run the initial self-configuration method, it is now executed
|
|
71
|
+
initial_self_configuration()
|
|
72
|
+
|
|
73
|
+
_logger = logging.getLogger(__name__)
|
|
74
|
+
# TODO At the moment it only collects models in AASX, think about whether to leave option to XML and JSON as well.
|
|
75
|
+
|
|
76
|
+
if file_path is None:
|
|
77
|
+
_logger.error("The file path to the AAS model is None, so it cannot be loaded.")
|
|
78
|
+
return
|
|
79
|
+
|
|
80
|
+
# The variable with the AAS model file name is updated
|
|
81
|
+
aas_model_file_name = ntpath.split(file_path)[1] or ntpath.basename(ntpath.split(file_path)[0])
|
|
82
|
+
# SMIAGeneralInfo.CM_AAS_MODEL_FILENAME = aas_model_file_name
|
|
83
|
+
GeneralUtils.update_aas_model(aas_model_file_name)
|
|
84
|
+
|
|
85
|
+
# The file will be copied into the SMIA archive
|
|
86
|
+
try:
|
|
87
|
+
smia_archive_utils.copy_file_into_archive(file_path, SMIAGeneralInfo.CONFIGURATION_AAS_FOLDER_PATH)
|
|
88
|
+
except Exception as e:
|
|
89
|
+
raise CriticalError('It is not possible to copy the specified AAS model into the SMIA Archive, so the SMIA '
|
|
90
|
+
'cannot be started. Reason: {}'.format(e))
|
|
91
|
+
_logger.info("AAS model {} copied to the SMIA Archive.".format(SMIAGeneralInfo.CM_AAS_MODEL_FILENAME))
|
|
92
|
+
|
|
93
|
+
# When the AAS model is inside the SMIA archive, it will be checked if it is valid
|
|
94
|
+
try:
|
|
95
|
+
config_file_path = AASModelUtils.get_configuration_file_path_from_standard_submodel()
|
|
96
|
+
init_config_file_name = ntpath.split(config_file_path)[1] or ntpath.basename(ntpath.split(config_file_path)[0])
|
|
97
|
+
config_file_bytes = AASModelUtils.get_file_bytes_from_aasx_by_path(config_file_path)
|
|
98
|
+
properties_file_utils.update_properties_file_by_bytes(config_file_bytes)
|
|
99
|
+
# with open(SMIAGeneralInfo.CONFIGURATION_FOLDER_PATH + '/' + init_config_file_name, "wb") as binary_file:
|
|
100
|
+
# binary_file.write(config_file_bytes) # Write bytes to file
|
|
101
|
+
# SMIAGeneralInfo.CM_GENERAL_PROPERTIES_FILENAME = init_config_file_name
|
|
102
|
+
except Exception as e:
|
|
103
|
+
_logger.warning("The AAS model does not contain the initialization configuration file. Make sure that it is "
|
|
104
|
+
"not necessary.")
|
|
105
|
+
|
|
106
|
+
# _logger.error(e)
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
from os import path
|
|
3
|
+
|
|
4
|
+
import basyx
|
|
5
|
+
from basyx.aas import model
|
|
6
|
+
from basyx.aas.adapter import aasx
|
|
7
|
+
from basyx.aas.util import traversal
|
|
8
|
+
|
|
9
|
+
from smia.logic.exceptions import CriticalError, AASModelReadingError
|
|
10
|
+
from smia.utilities import properties_file_utils
|
|
11
|
+
from smia.utilities.smia_general_info import SMIAGeneralInfo
|
|
12
|
+
|
|
13
|
+
_logger = logging.getLogger(__name__)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AASModelUtils:
|
|
17
|
+
"""This class contains utility methods related to the AAS model."""
|
|
18
|
+
|
|
19
|
+
@staticmethod
|
|
20
|
+
def read_aas_model_object_store():
|
|
21
|
+
"""
|
|
22
|
+
This method reads the AAS model according to the selected serialization format.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
basyx.aas.model.DictObjectStore: object with all Python elements of the AAS model.
|
|
26
|
+
"""
|
|
27
|
+
object_store = None
|
|
28
|
+
aas_model_file_path = properties_file_utils.get_aas_model_filepath()
|
|
29
|
+
aas_model_file_name, aas_model_file_extension = path.splitext(SMIAGeneralInfo.CM_AAS_MODEL_FILENAME)
|
|
30
|
+
try:
|
|
31
|
+
# The AAS model is read depending on the serialization format (extension of the AAS model file)
|
|
32
|
+
if aas_model_file_extension == '.json':
|
|
33
|
+
object_store = basyx.aas.adapter.json.read_aas_json_file(aas_model_file_path)
|
|
34
|
+
elif aas_model_file_extension == '.xml':
|
|
35
|
+
object_store = basyx.aas.adapter.xml.read_aas_xml_file(aas_model_file_path)
|
|
36
|
+
elif aas_model_file_extension == '.aasx':
|
|
37
|
+
with aasx.AASXReader(aas_model_file_path) as reader:
|
|
38
|
+
# Read all contained AAS objects and all referenced auxiliary files
|
|
39
|
+
object_store = model.DictObjectStore()
|
|
40
|
+
suppl_file_store = aasx.DictSupplementaryFileContainer()
|
|
41
|
+
reader.read_into(object_store=object_store,
|
|
42
|
+
file_store=suppl_file_store)
|
|
43
|
+
except ValueError as e:
|
|
44
|
+
_logger.error("Failed to read AAS model: invalid file.")
|
|
45
|
+
_logger.error(e)
|
|
46
|
+
raise CriticalError("Failed to read AAS model: invalid file.")
|
|
47
|
+
if object_store is None or len(object_store) == 0:
|
|
48
|
+
raise CriticalError("The AAS model is not valid. It is not possible to read and obtain elements of the AAS "
|
|
49
|
+
"metamodel.")
|
|
50
|
+
else:
|
|
51
|
+
return object_store
|
|
52
|
+
|
|
53
|
+
# Methods related to AASX Package
|
|
54
|
+
# -------------------------------
|
|
55
|
+
@staticmethod
|
|
56
|
+
def get_file_bytes_from_aasx_by_path(file_path):
|
|
57
|
+
"""
|
|
58
|
+
This method gets the bytes of a file appended inside an AASX package by a given internal path.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
file_path (str): the internal path of the file within the AASX package.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
obj: the content of the file in the form of bytes.
|
|
65
|
+
"""
|
|
66
|
+
with aasx.AASXReader(properties_file_utils.get_aas_model_filepath()) as aasx_reader:
|
|
67
|
+
for part_name, content_type in aasx_reader.reader.list_parts():
|
|
68
|
+
if part_name == file_path:
|
|
69
|
+
return aasx_reader.reader.open_part(part_name).read()
|
|
70
|
+
else:
|
|
71
|
+
_logger.warning("The file with path {} does not find within the AASX Package.".format(file_path))
|
|
72
|
+
return None
|
|
73
|
+
|
|
74
|
+
# Methods related to the AAS model
|
|
75
|
+
# --------------------------------
|
|
76
|
+
@staticmethod
|
|
77
|
+
def get_configuration_file_path_from_standard_submodel():
|
|
78
|
+
"""
|
|
79
|
+
This method gets the configuration file defined in the 'Software Nameplate' submodel, used as standard submodel
|
|
80
|
+
for the SMIA software definition.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
str: path inside the AASX package of the configuration file.
|
|
84
|
+
"""
|
|
85
|
+
# First, the AAS model need to be read
|
|
86
|
+
object_store = AASModelUtils.read_aas_model_object_store()
|
|
87
|
+
soft_nameplate_config_paths = AASModelUtils.get_elem_of_software_nameplate_by_semantic_id(object_store)
|
|
88
|
+
if soft_nameplate_config_paths is None:
|
|
89
|
+
raise CriticalError(
|
|
90
|
+
"Configuration of SMIA is required and it is not defined within the Software Nameplate submodel.")
|
|
91
|
+
for config_path_elem in soft_nameplate_config_paths:
|
|
92
|
+
sm_elem = config_path_elem.get_sm_element_by_semantic_id(
|
|
93
|
+
AASModelInfo.SEMANTIC_ID_SOFTWARE_NAMEPLATE_CONFIG_TYPE)
|
|
94
|
+
if (sm_elem is not None) and (sm_elem.value == 'initial configuration'):
|
|
95
|
+
return config_path_elem.get_sm_element_by_semantic_id(
|
|
96
|
+
AASModelInfo.SEMANTIC_ID_SOFTWARE_NAMEPLATE_CONFIG_URI).value
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def get_elem_of_software_nameplate_by_semantic_id(object_store):
|
|
101
|
+
"""
|
|
102
|
+
This method obtains a SubmodelElement of the Software Nameplate submodel.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
object_store (basyx.aas.model.DictObjectStore): storage with all AAS information,
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
basyx.aas.model.SubmodelElement: submodelElement with the given semanticID
|
|
109
|
+
"""
|
|
110
|
+
for object in object_store:
|
|
111
|
+
if isinstance(object, basyx.aas.model.Submodel):
|
|
112
|
+
if object.check_semantic_id_exist(AASModelInfo.SEMANTICID_SOFTWARE_NAMEPLATE_SUBMODEL):
|
|
113
|
+
for elem in traversal.walk_submodel(object):
|
|
114
|
+
if isinstance(elem, basyx.aas.model.SubmodelElement):
|
|
115
|
+
if elem.check_semantic_id_exist(AASModelInfo.SEMANTIC_ID_SOFTWARE_NAMEPLATE_CONFIG_PATHS):
|
|
116
|
+
return elem
|
|
117
|
+
return None
|
|
118
|
+
|
|
119
|
+
@staticmethod
|
|
120
|
+
async def get_key_type_by_string(key_type_string):
|
|
121
|
+
"""
|
|
122
|
+
This method gets the KeyType defined in BaSyx SDK related to the given string.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
key_type_string (str): string of the desired KeyType.
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
basyx.aas.model.KeyTypes: object of the KeyType defined in BaSyx.
|
|
129
|
+
"""
|
|
130
|
+
try:
|
|
131
|
+
return getattr(basyx.aas.model.KeyTypes, key_type_string)
|
|
132
|
+
except AttributeError as e:
|
|
133
|
+
_logger.error(e)
|
|
134
|
+
raise AASModelReadingError("The KeyType with string {} does not exist in the AAS model defined"
|
|
135
|
+
" types".format(key_type_string), sme_class=None, reason='KeyTypeAttributeError')
|
|
136
|
+
|
|
137
|
+
@staticmethod
|
|
138
|
+
async def get_model_type_by_key_type(key_type):
|
|
139
|
+
"""
|
|
140
|
+
This method gets the AAS model class by a given KeyType defined in BaSyx SDK.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
key_type (basyx.aas.model.KeyTypes): desired KeyType.
|
|
144
|
+
|
|
145
|
+
Returns:
|
|
146
|
+
object of the AAS model class.
|
|
147
|
+
"""
|
|
148
|
+
for model_class, key_type_class in basyx.aas.model.KEY_TYPES_CLASSES.items():
|
|
149
|
+
if key_type_class == key_type:
|
|
150
|
+
return model_class
|
|
151
|
+
return None
|
|
152
|
+
|
|
153
|
+
@staticmethod
|
|
154
|
+
async def create_aas_reference_object(reference_type, keys_dict=None, external_ref=None):
|
|
155
|
+
"""
|
|
156
|
+
This method creates the AAS BaSyx Reference Python object. Depending on the reference type to create (ModelReference or ExternalReference), some information is required. If a Reference cannot be created, it returns None.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
reference_type (str): type of the reference to be created (ModelReference or ExternalReference).
|
|
160
|
+
keys_dict (list): if ModelReference is selected, the required keys information in form of a JSON array.
|
|
161
|
+
external_ref (str): if ExternalReference is selected, the required globally unique identifier.
|
|
162
|
+
|
|
163
|
+
Returns:
|
|
164
|
+
basyx.aas.model.Reference: BaSyx Python object of the AAS Reference.
|
|
165
|
+
"""
|
|
166
|
+
ref_object = None
|
|
167
|
+
if 'ModelReference' == reference_type:
|
|
168
|
+
keys = ()
|
|
169
|
+
last_type = None
|
|
170
|
+
for key in keys_dict:
|
|
171
|
+
basyx_key_type = await AASModelUtils.get_key_type_by_string(key['type'])
|
|
172
|
+
keys += (model.Key(basyx_key_type, key['value']),)
|
|
173
|
+
last_type = basyx_key_type
|
|
174
|
+
ref_object = basyx.aas.model.ModelReference(
|
|
175
|
+
key=keys, type_=await AASModelUtils.get_model_type_by_key_type(last_type))
|
|
176
|
+
|
|
177
|
+
elif 'ExternalReference' == reference_type:
|
|
178
|
+
ref_object = model.ExternalReference((model.Key(type_=model.KeyTypes.GLOBAL_REFERENCE,
|
|
179
|
+
value=external_ref),))
|
|
180
|
+
return ref_object
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class AASModelInfo:
|
|
184
|
+
"""This class contains the information related to AAS model."""
|
|
185
|
+
SEMANTICID_SOFTWARE_NAMEPLATE_SUBMODEL = 'https://admin-shell.io/idta/SoftwareNameplate/1/0'
|
|
186
|
+
SEMANTICID_SOFTWARE_NAMEPLATE_INSTANCE_NAME = ('https://admin-shell.io/idta/SoftwareNameplate/1/0/SoftwareNameplate'
|
|
187
|
+
'/SoftwareNameplateInstance/InstanceName')
|
|
188
|
+
SEMANTIC_ID_SOFTWARE_NAMEPLATE_CONFIG_PATHS = ('https://admin-shell.io/idta/SoftwareNameplate/1/0'
|
|
189
|
+
'/SoftwareNameplate/SoftwareNameplateInstance/ConfigurationPaths')
|
|
190
|
+
SEMANTIC_ID_SOFTWARE_NAMEPLATE_CONFIG_TYPE = ('https://admin-shell.io/idta/SoftwareNameplate/1/0/SoftwareNameplate'
|
|
191
|
+
'/SoftwareNameplateInstance/ConfigurationType')
|
|
192
|
+
SEMANTIC_ID_SOFTWARE_NAMEPLATE_CONFIG_URI = ('https://admin-shell.io/idta/SoftwareNameplate/1/0/SoftwareNameplate'
|
|
193
|
+
'/SoftwareNameplateInstance/ConfigurationURI')
|
|
194
|
+
|
|
195
|
+
# TODO pasar aqui todos los IDs requeridos en el AAS (p.e el de AID submodel)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
class ExtendedAssetAdministrationShell:
|
|
2
|
+
"""This class contains methods to be added to AssetAdministrationShell class of Basyx Python SDK model."""
|
|
3
|
+
|
|
4
|
+
def print_aas_information(self):
|
|
5
|
+
print("AAS information:")
|
|
6
|
+
print("\tid: " + self.id)
|
|
7
|
+
print("\tid_short: " + self.id_short)
|
|
8
|
+
print("\tdisplayName:{}".format(self.display_name))
|
|
9
|
+
print("\tdescription:{}".format(self.description))
|
|
10
|
+
print("\tcategory: {}".format(self.category))
|
|
11
|
+
print("\tderivedFrom: {}".format(self.derived_from))
|
|
12
|
+
print("\tadministration: {}".format(ExtendedGeneralMethods.print_administration(self.administration)))
|
|
13
|
+
print("\textension: " + "{}".format(ExtendedGeneralMethods.print_namespace_set(self.extension)))
|
|
14
|
+
print("\tdataSpecifications: " + "{}".format(
|
|
15
|
+
ExtendedGeneralMethods.print_data_specifications(self.embedded_data_specifications)))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class ExtendedAssetInformation:
|
|
19
|
+
"""This class contains methods to be added to AssetInformation class of Basyx Python SDK model."""
|
|
20
|
+
|
|
21
|
+
def print_asset_information(self):
|
|
22
|
+
print("Asset information:")
|
|
23
|
+
print("\tassetKind: {}".format(self.asset_kind))
|
|
24
|
+
print("\tassetType: {}".format(self.asset_type))
|
|
25
|
+
print("\tspecificAssetId: {}".format(self.specific_asset_id))
|
|
26
|
+
print("\tglobalAssetId: {}".format(self.global_asset_id))
|
|
27
|
+
print("\tdefaultThumbnail: {}".format(self.default_thumbnail))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class ExtendedGeneralMethods:
|
|
31
|
+
|
|
32
|
+
@staticmethod
|
|
33
|
+
def print_administration(administration):
|
|
34
|
+
if administration:
|
|
35
|
+
return "version[{}".format(administration.version) + "], revision[{}".format(
|
|
36
|
+
administration.revision) + "], creator[{}".format(administration.creator) + "], templateId[{}".format(
|
|
37
|
+
administration.template_id) + "]"
|
|
38
|
+
else:
|
|
39
|
+
return ""
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def print_namespace_set(namespace_set):
|
|
43
|
+
string = ""
|
|
44
|
+
for item in namespace_set:
|
|
45
|
+
string += str(item) + ","
|
|
46
|
+
return string
|
|
47
|
+
|
|
48
|
+
@staticmethod
|
|
49
|
+
def print_data_specifications(embedded_data_specifications):
|
|
50
|
+
string = ""
|
|
51
|
+
for item in embedded_data_specifications:
|
|
52
|
+
string += ("(Reference: {}".format(item.data_specification) +
|
|
53
|
+
" | Content: {}".format(item.data_specification_content) + "),")
|
|
54
|
+
return string
|