eclipse-basyx / basyx-python-sdk Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
Where would be the best place to document this?
Is there the possibility to serialize to/from RDF?
If not, is it in the todo list, or it is not in the priority list?
Hello,
I am currently attempting to use your repository in conjunction with OPC UA to transfer Asset Administration Shell models. However, I'm facing some difficulties, particularly in the setup and configuration. Acutally i am a freshman about AAS.
I was wondering if it's possible for the community or contributors to provide an example or guide on how to achieve this. Any code snippets or pointers would be greatly appreciated.
Thanks in advance!
Serialize the Submodel to XML:
from basyx.aas.adapter import write_aas_xml_file
should be
from basyx.aas.adapter.xml import write_aas_xml_file
Furthermore, I had to change
with open('Simple_Submodel.xml', 'w', encoding='utf-8') as f:
to
with open('Simple_Submodel.xml', 'wb') as f:
to get it working.
Is this just my problem or a general one?
Classes Date, GYearMonth, GYear, GMonthDay, GDay, GMonth have tzinfo as a parameter and attribute. Why do these classes need the attribute? Does it make sense to remove the tzinfo from these classes?
With Version 3.0 the specification added several new sub-types of LangStringSet differing in the length of the string of the underlying LangString:
One option would be to implement the types directly and check the length constraints for example through dedicated getter and setter functions.
However, the modelling on the LangStringSet-Level done by the specification could be considered bad style. Therefore, we could decide to introduce a new abstract class LangString with classes inheriting from that class for the different types. We could do something like this:
DefinitionTypeIEC61360 is represented as a List of LangStringDefinitionTypeIEC61360
MultiLanguageNameType is represented as a List of LangStringNameType
PreferredNameTypeIEC61360 is represented as a List of LangStringPreferredNameTypeIEC61360
ShortNameTypeIEC61360 is represented as a List of LangStringShortNameTypeIEC61360
MultiLanguageTextType is represented as a List of Lang_string_text_type
As an added benefit, this would also bring us closer to the specified schemata, where LangStringSet-subtypes all have to be represented via native List objects. Also, this is equivalent to the implementation of aas-core
#86 added a missing model.KeyTypes.SUBMODEL_ELEMENT_LIST
.
The weird thing about this is that the unittests didn't catch this as a missing KeyType
, even though there are SubmodelElementList
s in the example test files.
We need to investigate, why the unittests didn't catch this missing KeyType
and improve the unittests, so that such mistake can not slip again in the future.
Currently, BlobType
is represented by the Python-Built in Type bytes
.
Comparing this to aas-core-meta, where it is represented as a bytearray
.
We should discuss, whether or not it makes sense to adapt aas-core-meta's representation.
The Constraint AASd-108 says: All first level child elements in a SubmodelElementList
shall have the same
submodel element type as specified in SubmodelElementList/typeValueListElement
.
The _check_constraints
method in SubmodelElementList
raises Exception if the child element in SubmodelElementList
is not of the same Class as it is specified in typeValueListElement.
So if I define my SDK for a specific Submodel and define classes for it (e.g. SpecialProperty
) which inherit from e.g. Property
class, i get Errors:
SubmodelElementList/typeValueListElement
to Property
SubmodelElementList
my SpecialProperty
object_check_constraints
, because SpecialProperty
!=Property
.SubmodelElementList/typeValueListElement
to SpecialProperty
, I get error from _submodel_element_list_to_json
in json_serialization.py because SpecialProperty
class is not in KEY_TYPES_CLASSES dictWhat are possible solutions here?
Some templates have bugs like admin-shell-io/submodel-templates#27
We need to mitigate them.
Possible solution: lower the first character of type when reading.
I am testing the Basyx registry component and I am having a problem when creating a new asset, saving it as AASX and sending it to the registry with the HTTP API .
As a test I have created a package from the example located here.
Afterwards I created a script to try to upload the package to the Basyx-registry but I get the following error:
{
"success": false,
"isException": true,
"messages": [{
"messageType": 6,
"code": "400",
"text": "MalformedRequestException: AssetAdministrationShellDescriptor is missing identification entry"
}]
}
The script I am using to send the asset (.aasx) is the following:
import requests
import json
from basyx.aas import model
from basyx.aas.adapter import aasx
import basyx.aas.adapter.json
def AddAsset(asset_path):
object_store: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
file_store = aasx.DictSupplementaryFileContainer()
with aasx.AASXReader(asset_path) as reader:
reader.read_into(object_store=object_store,
file_store=file_store)
#Store the serialized basyx json to debug the serialization
with open('data.json', 'w', encoding='utf-8') as json_file:
basyx.aas.adapter.json.write_aas_json_file(json_file, object_store)
json_aasx_str = basyx.aas.adapter.json.object_store_to_json(object_store)
json_aasx = json.loads(json_aasx_str)
# Assuming there is only one asset
asset_id = "asset_sample"
json_aasx["shortId"]= asset_id #Removes bug about missing shortId in Asset Admin. shell descriptor
registry_url = "http://localhost:8082/registry/api/v1/registry"
asset_put = registry_url+"/"+asset_id
payload = str(json_aasx)
r = requests.put(asset_put, data=payload)
print(r)
print(r.content)
#Asset generated with basyx-python-sdk example
asset_path = "MyAASXPackage.aasx"
AddAsset(asset_path)
I am not sure if I am doing something wrong as I am still new to the basyx middleware and would be helpful to get any feedback at to where the problem might be located. As additional info, I tested the sample JSON payload in the Swaggerhub API website and that works fine but building the package with basxy-python-sdk and serializing for the HTTP endpoint is not working as expected.
What I have noticed is that the serialized JSON from the basyx-python-sdk API does not have a 'shortId', which I fixed by adding this key to the dictionary.
I am trying to create an instance of basyx.aas.model.AASReference
and specify its type (see 5.7.10.2 of Details of the Asset Adminstration Shell Version 3.0RC02).
From the examples I see that you can add a key attribute and its type
What I dont see in the examples and the source code is how to specify the attribute type
to have the value ModelReference
: from the enumeration ReferenceTypes
from the spec.
Example of what I am trying to achieve:
keys= (model.Key(type_=model.KeyElements.SUBMODEL,
local=True,
value='MySubmodel',
id_type=model.KeyType.IDSHORT),
model.Key(type_=model.KeyElements.CAPABILITY,
local=True,
value='MyCapability',
id_type=model.KeyType.IDSHORT) )
my_ref= model.AASReference(keys,target_type= ModelReference)
Currently, the CI does not check if the sphinx autodoc documentation compiles.
We should add a check for that
SubmodelElement
instead of OperationVariable
in Operation
classOperationVariable
classThe problem occures by using adapter/xml_serialization.py/write_aas_xml_file(). The method has file as parameter, which should be of type IO, but I get Exception, that the expected type of parameter file is str
Traceback (most recent call last):
.........\basyx\aas\adapter\xml\xml_serialization.py", line 897, in write_aas_xml_file
tree.write(file, encoding="UTF-8", xml_declaration=True, method="xml", **kwargs)
File "src\lxml\etree.pyx", line 2057, in lxml.etree._ElementTree.write
File "src\lxml\serializer.pxi", line 758, in lxml.etree._tofilelike
File "src\lxml\etree.pyx", line 318, in lxml.etree._ExceptionContext._raise_if_stored
File "src\lxml\serializer.pxi", line 682, in lxml.etree._FilelikeWriter.write
TypeError: write() argument must be str, not bytes
How does the compliance tool work exactly? I tried to validate some same valid aasx.json files with the compliance tool, but It always shows the test failed.
The only time test was successful was when I ran the same files generated from examples that are already inside this repo.
The following types have to be implemented for v3.0
See the specifcation
ContentType
Identifier
LabelType
MessageTopicType
NameType
PathType
Note: Here we may want to constrain the string furtherRevisionType
Note: Here we may want to constrain the string furtherQualifierType
VersionType
If we decide to also fully implement Part 3a, we need the following types as well link to spec:
PreferredNameTypeIec61360
ShortNameTypeIec61360
ValueFormatTypeIec61360
ValueTypeIec61360
After the spec regarding language tags is clarified(admin-shell-io/aas-specs#293), we need to adapt the method LangStringSet._check_language_tag_constraints
Currently we demand that language tags:
Relevant codesnippet:
https://github.com/eclipse-basyx/basyx-python-sdk/blob/5eb895e1e64cdcd4ba98464d5fda4176292cf942/basyx/aas/model/base.py#L289C1-L296C56
@classmethod
def _check_language_tag_constraints(cls, ltag: str):
split = ltag.split("-", 1)
if len(split[0]) != 2 or not split[0].isalpha() or not split[0].islower():
raise ValueError(f"The language code '{split[0]}' of the language tag '{ltag}' doesn't consist of exactly "
"two lower-case letters!")
if len(split) > 1 and (len(split[1]) != 2 or not split[1].isalpha() or not split[1].isupper()):
raise ValueError(f"The extension '{split[1]}' of the language tag '{ltag}' doesn't consist of exactly "
"two upper-case letters!")
I've set up a AAS server and request all submodels. I generate it like this:
submodel = model.Submodel(
identification=model.Identifier(
"https://acplt.org/Simple_Submodel", model.IdentifierType.IRI
),
submodel_element={
model.Property(
id_short="ExampleProperty",
value_type=basyx.aas.model.datatypes.String,
value="exampleValue",
)
},
)
submodel_json_string = json.dumps(submodel, cls=basyx.aas.adapter.json.AASToJsonEncoder)
and then simply upload it via a PUT
request to the aasServer.
Afterwards I GET
the submodel again and the payload from AAS server looks like this
{
"idShort": "",
"modelType": {
"name": "Submodel"
},
"identification": {
"id": "https://acplt.org/Simple_Submodel",
"idType": "IRI"
},
"submodelElements": {
"ExampleProperty": {
"idShort": "ExampleProperty",
"modelType": {
"name": "Property"
},
"semanticId": {
"keys": [
{
"type": "GlobalReference",
"idType": "IRI",
"value": "http://acplt.org/Properties/SimpleProperty",
"local": false
}
]
},
"value": "exampleValue",
"valueType": "string"
}
}
}
which fails with TypeError: Dict entry 'submodelElements' has unexpected type dict
this is a bit different from what the json serialization from python returns:
{
"idShort": "",
"modelType": {
"name": "Submodel"
},
"identification": {
"id": "https://acplt.org/Simple_Submodel",
"idType": "IRI"
},
"submodelElements": [
{
"idShort": "ExampleProperty",
"modelType": {
"name": "Property"
},
"semanticId": {
"keys": [
{
"type": "GlobalReference",
"idType": "IRI",
"value": "http://acplt.org/Properties/SimpleProperty",
"local": false
}
]
},
"value": "exampleValue",
"valueType": "string"
}
]
}
Why is the json deserialization incompatible?
I assume that the parent attribute of the submodel should be set automatically after it has been added to an AAS. However, in contrast to other elements, it remains None.
It would be nice to implement this feature to better find the corresponding aas of a submodel.
Hi,
I am using the official docker image of AAS server (eclipsebasyx/aas-server:1.3.0). However, the JSON response of AAS server is different than basyx-python-sdk JSON serialization result (Version: 0.2.2)
For example, when kind of submodel is instance there is no "kind":"Instance"
in the output. In the image below you can see the structure is not consistent and this is reflected in the code too, however I don't know this is according to specification or just implementaiton difference.
And here you can see there are asset
and assetRef
on the left produced by AAS server. python sdk asset
is equivalent to assetRef
and asset
is completely missing.
Is there any way to reproduce exact result of AAS server in python? or which java library should be used, basyx-java-sdk or eclipse-aas4j/aas4j or something else?
Please let me know if you require further information.
Constraint AASd-133: SpecificAssetId/externalSubjectId shall be a global reference, i.e. Reference/type = GlobalReference.
See here
According to the spec: AASd-130:
Ensures that encoding is possible and interoperability between different
serializations is possible.
Constraint AASd-130: An attribute with data type "string" shall consist of these
characters only: ^[\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u00010000-
\u0010FFFF]*$.
My suggestion is to add this regex to the general check()
function
Dear team,
# For adding a second AAS to the package, we can simply call `write_aas()` again.
# Warning: This will create a second XML/JSON part in the AASX Package, which is compliant with the "Details of the
# Asset Administration Shell" standard up to version 2.0.1, but not supported by AASX Package Explorer.
could someone update me on a status of AASX-package-explorer versions of multiple AAS in the AASX package?
When checking https://admin-shell-io.com/samples/aasx/22_Festo.aasx the compliance tool crashes due to an unhandled exception:
python3 ./basyx/aas/compliance_tool/cli.py -vv d --aasx --json 22_Festo.aasx
Traceback (most recent call last):
File "~/.local/lib/python3.8/site-packages/pyecma376_2/package_model.py", line 150, in open_part
part_descriptor = self._parts[normalize_part_name(name)]
KeyError: '/thumbnail.jpg'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "./basyx/aas/compliance_tool/cli.py", line 189, in <module>
main()
File "./basyx/aas/compliance_tool/cli.py", line 151, in main
compliance_tool_aasx.check_deserialization(args.file_1, manager)
File "~/Projects/basyx-python-sdk/basyx/aas/compliance_tool/compliance_check_aasx.py", line 86, in check_deserialization
reader.read_into(obj_store, files)
File "~/Projects/basyx-python-sdk/basyx/aas/adapter/aasx.py", line 151, in read_into
self._read_aas_part_into(aas_part, object_store, file_store, read_identifiables, override_existing)
File "~/Projects/basyx-python-sdk/basyx/aas/adapter/aasx.py", line 206, in _read_aas_part_into
self._collect_supplementary_files(part_name, obj, file_store)
File "~/Projects/basyx-python-sdk/basyx/aas/adapter/aasx.py", line 257, in _collect_supplementary_files
with self.reader.open_part(absolute_name) as p:
File "~/.local/lib/python3.8/site-packages/pyecma376_2/package_model.py", line 152, in open_part
raise KeyError("Could not find part {} in package".format(name)) from e
KeyError: 'Could not find part /thumbnail.jpg in package'
The current behavior of the id_short
attribute of Refereable
objects is causing unexpected behavior in the codebase. It defaults to the string literal "NotSet" by default. This is problematic because it can lead to confusion and unexpected results when developers interact with this attribute.
We shoud find some other solution for idShort
Setting a "0" as value of a property (data type: int, float, double, ..) is converted by the SDK into the value None.
V3.0 changed model.Entity.specific_asset_id
: https://rwth-iat.github.io/aas-specs/AASiD_1_Metamodel/index.html#Entity
We need to adapt these changes.
@jkhsjdhjs Could you do this?
For an Operation, the idShort of all inputVariable/value, outputVariable/value, and inoutputVariable/value shall be unique.
See here
Constraint AASd-129: If any Qualifier/kind value of a SubmodelElement/qualifier (attribute qualifier inherited
via Qualifiable) is equal to TemplateQualifier, the submodel element shall be part of a submodel template,
i.e. a Submodel with Submodel/kind (attribute kind inherited via HasKind) value equal to Template.
Any suggestions as to how to implement this?
In the same step, we should probably also implement AASd-119:
If any Qualifier/kind value of a Qualifiable/qualifier is equal to TemplateQualifier and
the qualified element inherits from "hasKind", the qualified element shall be of kind Template (HasKind/kind =
"Template").
The AASX Package Explorer's XML De-/Serialization of multiple qualifiers does not fully conform to the Schema, as indicated in https://github.com/admin-shell-io/temp-aasx-package-explorer/issues/99.
However, it would be beneficial if the basyx-python SDK could still deserialize all qualifiers, even if they do not conform to the Schema, and print a warning accordingly.
Hi, in Details of the Asset Administration Shell - Part 1 version 2.0.1 the xsd datatype are listed as below:
however when I am trying to parse my AASX file, I get the following error:
ValueError: aas:valueType on line 472 has invalid text: dateTimeStamp
-> Failed to construct aas:property on line 456 using construct_submodel_element!
It seems that for basyx-python-sdk these datatypes are used:
https://www.w3.org/TR/xmlschema-2/#built-in-datatypes
but in the specification the following newer specified datatypes are used:
https://www.w3.org/TR/xmlschema11-2/#built-in-datatypes
Could you please clear that?
IEC61360ConceptDescription
is removed since V30RC02. New classes HasDataSpecification
, Embedded_data_specification
, DataSpecificationContent
, DataSpecificationIEC61360
and DataSpecificationPhysicalUnit
are introduces instead.
Thatยดs why affected methods and classes in the following files should be updated:
Now it is allowed to create Reference object with empty key tuple like this: a=Reference(tuple())
According to the Metamodel len of key tuple must >=1
Implement a function to check_schema for AASX files in aas/compliance_tool/compliance_check_aasx.py
Idea:
Hi,
How do I add a property to a SubmodelElementCollection?
With the following code I am able to create and add a SubmodelElementCollection to a Submodel.
smc= model.SubmodelElementCollectionUnordered(id_short="TestSME")
submodel.submodel_element.add(smc)
I am not able to add a property to that smc. The following code below gives error: AttributeError: 'SubmodelElementCollectionUnordered' object has no attribute 'submodel_element'.
smc.submodel_element.add(property_)
Is there a way to add a property to a SubmodelElementCollection?
The sdk reads existing files with unsupported metamodell versions without throwing exceptions. The file contents will be not read.
Suggestion:
I am trying to see if I can import a template, in specific the Digital Nameplate. The aasx packages are located here .
Whenever I try to use the aasx.Reader
and call read_into
I get the following error:
KeyError: aas:mimeType on line 505 has no text!
-> Failed to construct aas:file on line 495 using construct_submodel_element!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 590 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 627 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 664 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 701 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 738 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 775 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 812 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 849 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 886 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 923 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 960 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 997 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1034 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1071 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1108 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1145 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1182 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1219 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1256 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1293 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1330 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1367 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1404 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1441 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1478 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1515 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1552 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1589 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1626 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1659 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1691 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1723 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1755 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1787 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1819 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1851 using construct_administrative_information!
ValueError: A revision requires a version. This means, if there is no version there is no revision neither.
-> Failed to construct aas:administration on line 1888 using construct_administrative_information!
IEC61360ConceptDescription[Identifier(IRI=https://admin-shell.io/zvei/nameplate/1/0/Nameplate)] has a duplicate identifier already parsed in the document! skipping it...
Code with the problem
template_path= "SMT_pure_ZVEI_Digital_Nameplate_V10.aasx"
new_object_store: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
new_file_store = aasx.DictSupplementaryFileContainer()
with aasx.AASXReader(template_path) as reader:
reader.read_into(object_store=new_object_store,
file_store=new_file_store)
Was removed in v3.0
It would appear, that improve/V30 does not yet contain the changes to class ConceptDescription
that were introduced in V3.0.
Before the release, we need to adapt these changes.
When instantiating an AssetAdministrationShell
-object, we hand over ConceptDictionary
s in any kind of Iterable
(See here)
def __init__(self,
...
concept_dictionary: Iterable[concept.ConceptDictionary] = (),
...):
However, internally, we create a NamespaceSet
containing these ConceptDictionary
s in order to be able to resolve them later:
self.concept_dictionary: base.NamespaceSet[concept.ConceptDictionary] = \
base.NamespaceSet(self, concept_dictionary)
Now, if a user were to only look at the initialization parameters, and wanted to add a ConceptDictionary
later, after initalization, they could theoretically assume, they could set it like this:
my_aas.concept_dictionary = [my_concept_dictionary]
This would have terrible results when iterating over ObjectStore
s containing these objects, since suddenly, we'd get the (not very helpful) error:
AttributeError: 'list' object has no attribute 'update_nss_from'
This obviously points nowhere in the right direction.
I have the suspicion, that this is not the only time, where such a problem may arise. How can we restrrict the user from making such a mistake in the first place? Should we write getter and setter functions for these kinds of attributes? On the other hand, maybe this is something to be checked by the ObjectStore
, when adding an item to it?
Each class that inherits from the abstract class base.Identifiable has an attribute id
.
By default, id
is set to Identifier("").
The new Version 3.0 contains a constraint, that Identifier has a minimum of one character.
Therefore, it's necessary to set id
to a new default value.
The current spec describes id as of type Identifier which prohibits the use of None.
We should discuss a suitable solution.
When parsing an AssetAdministrationShell from json _construct_asset_administration_shell
is expecting a type dict
in asset
element:
def _construct_asset_administration_shell(
cls, dct: Dict[str, object], object_class=model.AssetAdministrationShell) -> model.AssetAdministrationShell:
ret = object_class(
asset=cls._construct_aas_reference(_get_ts(dct, 'asset', dict), model.Asset),
identification=cls._construct_identifier(_get_ts(dct, 'identification', dict)))
However, at that point the asset
element is already parsed and fails with:
TypeError: Dict entry 'asset' has unexpected type Asset
Changing the above line to
def _construct_asset_administration_shell(
cls, dct: Dict[str, object], object_class=model.AssetAdministrationShell) -> model.AssetAdministrationShell:
ret = object_class(
asset=get_ts(dct, 'asset', model.Asset),
identification=cls._construct_identifier(_get_ts(dct, 'identification', dict)))
seems to fix the problem.
Example python code:
json_ = """
[
{
"conceptDictionary": [],
"assetRef": {
"keys": [
{
"idType": "IRI",
"type": "Asset",
"value": "1030_8141_0112_5510",
"local": true
}
]
},
"identification": {
"idType": "IRI",
"id": "1220_8141_0112_0875"
},
"idShort": "AAS",
"dataSpecification": [],
"derivedFrom": {
"keys": [
{
"idType": "IdShort",
"type": "AssetAdministrationShell",
"value": "6455_1111_0112_4769",
"local": true
}
]
},
"modelType": {
"name": "AssetAdministrationShell"
},
"asset": {
"idShort": "CA",
"modelType": {
"name": "Asset"
},
"identification": {
"id": "1030_8141_0112_5510",
"idType": "IRI"
},
"kind": "Instance"
},
"embeddedDataSpecifications": [],
"views": []
}
]
"""
shells = json.loads(json_, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
The README is missing a link to our hosted documentation (https://basyx-python-sdk.readthedocs.io/en/latest/)
Furthermore, the required steps to contribute should be laid out more clearly (see the comments in #13)
When loading an AASX file, the aasx checks all submodels for File
elements and tries to resolve the referenced files relative to the aasx container root. In Version 2.0, a document named TestFile.pdf
in the AASX packages root would be referenced by a File
element via the path /TestFile.pdf
.
Since version 3.0, the schemata prohibit values like /TestFile.pdf
and require the file://
protocol to be used, e.g. file:///TestFile.pdf
. The problem is that File
also supports remote references to files, for example via https://
. This isn't allowed by the new schemata.
We should discuss whether the restrictions imposed by the schemata are actually correct, and if so, change the aasx adapter and examples accordingly.
See also:
basyx-python-sdk/basyx/aas/examples/data/example_aas.py
Lines 470 to 471 in 8304c2a
basyx-python-sdk/basyx/aas/adapter/aasx.py
Lines 233 to 259 in 8304c2a
Currently no De/Serialisation of values with datatype "decimal" is given.
Implementation needed in basyx.aas.model.datatypes.from_xsd()
and basyx.aas.model.datatypes.xsd_repr()
.
Tracking issue for V3.0 release.
TODOs:
id_short
attribute defaulting to the string literal NotSet
(see discussion on Zulip)NamespaceSet
immutable (inherit from FrozenSet
) and rename the current NamespaceSet
to MutableNamespaceSet
, which inherits from the new immutable NamespaceSet
-> for SubmodelElementCollection
improve/V30 schemata
and adapt if necessary -> see below(s-heppner, 2023-10-19)
EDIT: Copied comment from below, so that not just me can edit. Furtheremore, I took the liberty to clean up this comment.
Since we're closing in to the last steps, here a summary of the Todos left before the v3.0 Release:
unit
at first glance)Issue:
We've been using our proprietary test set for validating the SDK against the metamodel. However, with every change in the metamodel that necessitates an update to our SDK, we find ourselves having to make corresponding adjustments to our test data. This iterative process is resource-intensive and can lead to potential inconsistencies and oversights.
Proposal:
To streamline this process and ensure a more robust testing framework, we recommend transitioning to the test data provided by aas-core3.0-testgen
. Here are the key benefits of making this switch:
Comprehensive Coverage: The aas-core3.0-testgen
provides an extensive set of test data, ensuring thorough validation of our SDK against a wide range of scenarios.
Automatic Generation: The test data from aas-core3.0-testgen
is automatically generated, which means we'll always have the most up-to-date test cases without the manual effort of creating or updating them.
Reduced Maintenance: By relying on this external test set, we can significantly reduce the overhead associated with maintaining our own test data. This will allow our team to focus on enhancing the SDK and addressing other critical priorities.
Consistency with the Community: Adopting a widely-used test set ensures that our SDK is in alignment with community standards and best practices.
Next Steps:
We should initiate a transition plan to integrate aas-core3.0-testgen
test data into our testing pipeline. This will involve:
aas-core3.0-testgen
.Currently, our base URL for the AASX namespace is
http://www.admin-shell.io/aasx/
In the specification, the base URL for the AASX namespace is
http://admin-shell.io/aasx/
We need to remove the www.
subdomain to be compliant to the spec.
Currently there is no information to which version of the AAS specification the SDK is compliant to. It would be helpful, if this could be added by using tags as it is done in the original repository at https://git.rwth-aachen.de/acplt/pyi40aas.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.