Skip to content
Snippets Groups Projects
Commit 699b31d4 authored by Ahmed Osman's avatar Ahmed Osman
Browse files
parents bcba08be 3326e0cb
No related branches found
No related tags found
No related merge requests found
Pipeline #331036 passed
### General
The latest version of the demo consists mainly of three communication partners: demo2_dzwald.py, demo2_forestmanager.py (which represents the Dienstleister) and demo2_forestmanager_waldbesitzer.py (which as the name implies represents the forest owner).
demo2_dzwald.py uses the S3IBServer Component from broker_api.py to expose an underlying AAS through the AAS-Interface.
......@@ -35,8 +37,106 @@ To await specific messages, S3IBAsyncClient's awaitMessage method can be used. T
demo2_forestmanager_waldbesitzer.py updates the security submodel, then notifies demo2_forestmanager.py using the
S3IBAsyncClient's sendUserMessage Method:
`await client.sendUserMessage(forstify_hmi_id, "s3ibs://" + forstify_hmi_id, "Authorized", "Authorized")`
(foristify_hmi_id here is a naming mistake)
`await client.sendUserMessage(forestmanager_hmi_id, "s3ibs://" + forestmanager_hmi_id, "Authorized", "Authorized")`
### Security and Authorization
Security-related data can be stored in the security submodel (refer to /model/security.py). It contains AccessControl, a SubmodelElementList of AccessRuleCollection. The latter is a SubmodelElementCollection, that contains a SubmodelElementList of AccessPermissonRule (a SubmodelElementCollection with the user the permission is being granted to, the permission type for example ALLOW, and the permisson for example READ) and the Target (a ReferenceElement that refers to the AAS-Element the rules apply to).
```
rules = [security.AccessPermissionRule(forestmanager_hmi_id,
security.PermissionKind.ALLOW,
security.Permission.READ),
security.AccessPermissionRule(forestmanager_hmi_id,
security.PermissionKind.ALLOW,
security.Permission.WRITE)]
rules_smc = security.AccessPermissionCollection(
target=model.ModelReference.from_referable(aas_dz_wald),
rules=rules
)
access_control = security.AccessControl(permissions=[rules_smc])
security_sm = security.Security("https://www.company.com/security")
security_sm.add_referable(access_control)
```
Since permission-granting decisions are made by the opa-server (if security enabled), this data must provided (in simpler format) to it and continiously updated (if changes occur). This is handled by the S3IBServer Component utilizing the security.py::get_dict_from_security_submodel method.
### Events
Create server-side Events (S3IBServer expects events to be stored in a separate submodel with a fixed id).
In the following, any changes (received set-Requests) to Auftragsstatus cause an event message to be sent to topic123 (and all queues bound/subscribed to it):
```
events = model.Submodel(
id_="https://www.company.com/submodels/events",
id_short="Events"
)
event = model.BasicEventElement(
id_short="Auftragsstatus_Updated",
observed=model.ModelReference.from_referable(arbeitsauftrag.get_referable(configs.AUFTRAGSSTATUS)),
direction=model.Direction.OUTPUT,
state=model.StateOfEvent.ON,
message_topic="topic123"
)
events.add_referable(event)
```
On client-side events can be subscribed to and awaited using S3IBAsyncClient's awaitEvent method:
```
events_submodel_id = "https://www.company.com/submodels/events"
events_submodel_id_encoded = base64.urlsafe_b64encode(events_submodel_id.encode()).decode()
event: model.BasicEventElement = await client.getValue(dzwald_id, dzwald_endpoint,
f"/aas/submodels/{events_submodel_id_encoded} \
/submodel/submodelElements/Auftragsstatus_Updated")
auftragsstatus_updated = await client.awaitEvent(event.message_topic)
```
### Operations
Operation Submodelelements can be thought of operation descriptions. The actual callable/invokable is added to the S3IBServer (alongside the operation path for authorization purposes):
```
getHolzpreisbereich_op = model.Operation(
id_short="getHolzpreisbereich",
input_variable=[model.OperationVariable(model.Property(
id_short="HolzlisteId",
value_type=model.datatypes.String
))]
)
holzliste.add_referable(getHolzpreisbereich_op)
...
def getHolzpreisbereich(provider: api.ModelProvider, HolzlisteId: str):
...
return reply
...
callable = lambda **kwargs : getHolzpreisbereich(provider, **kwargs)
operation_path = f"/aas/submodels/{helpers.encode_id(HolzlisteId)}/submodel/submodelElements/getHolzpreisbereich"
server.add_callable(operation_path, callable)
```
Invoke the Operation using S3IBAsyncClient's invokeOperation method:
```
HolzlisteId = "https://www.company.com/holzliste/1"
reply4 = await client.invokeOperation(
dzwald_id,
dzwald_endpoint,
f"/aas/submodels/{helpers.encode_id(HolzlisteId)}/submodel/submodelElements/getHolzpreisbereich",
{"HolzlisteId": HolzlisteId}
)
print(f"result of operation 'getHolzpreisbereich': {reply4}")
```
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment