fml40 python reference implementation
==============================
Reference implementation for building a Digital Twin based on the Forest Modeling Language 4.0 (fml40), as specified in [this white paper](https://www.kwh40.de/wp-content/uploads/2020/03/KWH40-Standpunkt-fml40-Version-1.0.pdf) (in German).
# Installation
To use the fml40 reference implementation package in your own project, install it from Pypi
```
python -m pip install fml40-reference-implementation
```
Documentation
--------
We provide a documentation to get start with the fml40 python reference implementation package. It can be found [here](https://kwh40.pages.rwth-aachen.de/fml40-reference-implementation).
Features
--------
This package provides two different modes to launch your Digital Twins:
- Launching Digital Twin quickly in persistent mode via `fml40s.py`. You need to register a thing identity for your Digital Twin via [S³I Config REST API](https://config.s3i.vswf.dev/apidoc) and prepare a respective config file that describes a fml40-compliant DT in JSON. For more details, refer to the example `MyDigitalTwin.json` in the section `Config files`.
- Extending the capabilities with user defined Digital Twins, which means you can additionally define and insert a function according to ForestML 4.0 into the Digital Twin. We provide an exemplary Digital Twin built in [Jupyter Notebook](https://mybinder.org/v2/gh/kwh40/notebooks/master), refer to notebooks `08a`, `08b`, `08d` and `08e`.
Usage
-----
### Using fml40s.py
A Digital Twin can be launched in persistent mode by executing
```
python fml40s.py launch <CONFIG_FILE>
```
Config files for Digital Twin must be located in the folder `configs`.
For more options call just run
```
python fml40s.py -h
```
### Develop your Digital Twin using this package
Here, we introduce briefly how to develop a user-specified Digital Twin. For more details, refer to the cloud/edge Digital Twin built in [Jupyter Notebook](https://mybinder.org/v2/gh/kwh40/notebooks/master).
The following steps can only be carried out after you have created the thing identity of your Digital Twin via S³I Config REST API and made a respective config file. Here, we use the config file `MyDigitalTwin.json` from section `Config files`. Now we continue the following steps:
- Optionally, set a logger using the function `setup_logger`. The generated log file will then be located in the folder `logs`.
```
ml.setup_logger("MyDigitalTwin")
```
- Set the path of the config file and import it in JSON format.
```
config_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "configs"))
dt_model = ml.load_config(config_filepath=os.path.join(config_path, "MyDigitalTwin.json"))
```
- Create the thing instance.
```
client_secret = "" #To be filled
thing = ml.create_thing(
model=dt_model, grant_type="client_credentials", secret=client_secret,
is_broker_rest=False, is_broker=True, is_repo=True
)
```
- As specified in the config file, the Digital Twin has a feature named fml40::ProvidesProductionData. In the next step, we extend/implement this class with our own logic.
```
class ProvidesProductionDataImpl(ProvidesProductionData):
def __init__(self, name="", identifier=""):
super(ProvidesProductionData, self).__init__(
name=name,
identifier=identifier)
self.production_data_list = thing.features["ml40::ProductionData"].subFeatures["ml40::Composite"].targets
def getProductionData(self, name):
for key in self.production_data_list.keys():
if key == name:
return self.production_data_list[key].to_subthing_json()
return {"error": "NOT FOUND"}
```
- Insert the class into the respective feature of your Digital Twin
```
ml.add_function_impl_obj(thing, ProvidesProductionDataImpl, "fml40::ProvidesProductionData")
```
- Launch your Digital Twin
```
thing.run_forever()
```
So far, your Digital Twin has been created. In the meantime, you can establish a connection with it using S³I-B messages.
Config files
------------
A valid configuration consists of exactly one JSON object. Mandatory fields of the JSON object are
- thingId
- policyId and
- attributes
The configuration file must be created in accordance with ForestML 4.0, refer to Cap. 7.1 of the [KWH4.0 ForestML 4.0 white paper](https://www.kwh40.de/wp-content/uploads/2020/03/KWH40-Standpunkt-fml40-Version-1.0.pdf). Additionally, we provide an exemplary JSON config file, see below.
MyDigitalTwin.json:
```
{
"thingId": "s3i:id",
"policyId": "s3i:id",
"attributes": {
"class": "ml40::Thing",
"name": "my digital twin",
"roles": [
{
"class": "fml40::Harvester"
}
],
"features": [
{
"class": "fml40::ProvidesProductionData"
},
{
"class": "ml40::ProductionData",
"subFeatures": [
{
"class": "ml40::Composite",
"targets": [
{
"class": "ml40::Thing",
"name": "Stammsegment 4711",
"roles": [
{
"class": "fml40::StemSegment",
}
],
"features": [
{
"class": "ml40::Location",
"latitude": 50.1231,
"longitude": 6.1231
},
{
"class": "fml40::StemSegmentProperties",
"diameter": 0.4,
"length": 2,
"woodType": "Spruce"
}
]
},
{
"class": "ml40::Thing",
"name": "Stammsegment 4712",
"roles": [
{
"class": "fml40::StemSegment",
}
],
"features": [
{
"class": "ml40::Location",
"latitude": 50.1231,
"longitude": 6.1231
},
{
"class": "fml40::StemSegmentProperties",
"diameter": 0.6,
"length": 3,
"woodType": "Spruce"
}
]
}
]
}
]
},
{
"class": "ml40::Location",
"longitude": 5.03424,
"latitude": 52.52345
}
]
}
}
```
Structure
---------
### Configs
This folder contains configuration files in JSON format for Digital Twins.
### ml
This directory includes the implementations of the fml40 python reference implementation as described in the KWH ForestML 4.0 white paper.
### demo
Example for creating and launching an HMI, which is used to communicate with the permanent Digital Twin using S³I-B protocol.
### logs
This folder contains the log files of the created and launched Digital Twins.
### tests
This folder contains all test scripts (currently in development).