Test ASAM ODS EXD-API Plugins#

Once you have created your (first) EXD-API Plugin, you can now do a simple test, if it will work in combination with an ASAM ODS server.

Therefore, the meta data will be read first (GetStructure) during the “Import Phase”; afterward the channel/bulk data (GetValues) is being accessed.

Prepare Python Environment to access GRPC Service#

import os
import pathlib

import grpc
from google.protobuf.json_format import MessageToJson

from odsbox.proto import ods_external_data_pb2
from odsbox.proto import ods_external_data_pb2_grpc

EXD-API#

The EXD-API Plugin is running as a RPC service at a given URL. Running exd_api_server.py´will run the plugin at the given URL.

exd_api_plugin_url = "localhost:50051"

Import Phase#

We will open a MDF4 file using the EXD-API and extract the internal structure of the file to import it into the ASAM ODS server.

data_file_path = os.path.abspath("data/simple.mf4")
if not os.path.exists(data_file_path):
    raise Exception("Data file is missing")
import_file_url = pathlib.Path(data_file_path).as_uri()
import_file_parameters = ""
print(import_file_url)

# Will be filled from Structure
access_file_url = None
access_file_parameters = None
file:///c:/Users/AKR/github/asam_ods_exd_api_mdf4/data/simple.mf4

Extract Infos from Structure#

The structure contains infos about groups and channels to create corresponding measurements, submatrices and measurement_quantities

with grpc.insecure_channel(exd_api_plugin_url) as channel:
    stub = ods_external_data_pb2_grpc.ExternalDataReaderStub(channel)

    # import file into ASAM ODS Server physical storage
    import_identifier = ods_external_data_pb2.Identifier(url=import_file_url, parameters=import_file_parameters)

    import_handle = stub.Open(import_identifier)
    try:
        structure = stub.GetStructure(ods_external_data_pb2.StructureRequest(handle=import_handle))
        print(MessageToJson(structure))

        access_file_url = structure.identifier.url
        access_file_parameters = structure.identifier.parameters

        for group in structure.groups:
            group_id = group.id
            for channel in group.channels:
                channel_id = channel.id
    finally:
        stub.Close(import_handle)
{
  "identifier": {
    "url": "file:///c:/Users/AKR/github/asam_ods_exd_api_mdf4/data/simple.mf4",
    "parameters": ""
  },
  "name": "simple.mf4",
  "groups": [
    {
      "id": "0",
      "name": "",
      "totalNumberOfChannels": "10",
      "numberOfRows": "563",
      "channels": [
        {
          "id": "0",
          "name": "time",
          "dataType": "DT_DOUBLE",
          "unitString": "s",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    ""
                  ]
                }
              }
            }
          }
        },
        {
          "id": "1",
          "name": "abs_time",
          "dataType": "DT_LONGLONG",
          "unitString": "ns",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    "absolute timestamp in nano seconds"
                  ]
                }
              }
            }
          }
        },
        {
          "id": "2",
          "name": "acc_x",
          "dataType": "DT_LONG",
          "unitString": "mg",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    "acceleration x in millie gram"
                  ]
                }
              }
            }
          }
        },
        {
          "id": "3",
          "name": "acc_y",
          "dataType": "DT_LONG",
          "unitString": "mg",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    "acceleration y in millie gram"
                  ]
                }
              }
            }
          }
        },
        {
          "id": "4",
          "name": "acc_z",
          "dataType": "DT_LONG",
          "unitString": "mg",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    "acceleration z in millie gram"
                  ]
                }
              }
            }
          }
        },
        {
          "id": "5",
          "name": "light",
          "dataType": "DT_LONG",
          "unitString": "-",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    "luminosity"
                  ]
                }
              }
            }
          }
        },
        {
          "id": "6",
          "name": "temp",
          "dataType": "DT_LONG",
          "unitString": "degC",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    "temperature in degree celsius"
                  ]
                }
              }
            }
          }
        },
        {
          "id": "7",
          "name": "comp_x",
          "dataType": "DT_LONG",
          "unitString": "nT",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    "compass x in nano tesla"
                  ]
                }
              }
            }
          }
        },
        {
          "id": "8",
          "name": "comp_y",
          "dataType": "DT_LONG",
          "unitString": "nT",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    "compass y in nano tesla"
                  ]
                }
              }
            }
          }
        },
        {
          "id": "9",
          "name": "comp_z",
          "dataType": "DT_LONG",
          "unitString": "nT",
          "attributes": {
            "variables": {
              "description": {
                "stringArray": {
                  "values": [
                    "compass z in nano tesla"
                  ]
                }
              }
            }
          }
        }
      ],
      "attributes": {}
    }
  ],
  "attributes": {}
}

Access Bulk Data#

With the stored information the ASAM ODS server can access the bulk data from the EXD-API Plugin

with grpc.insecure_channel(exd_api_plugin_url) as channel:
    stub = ods_external_data_pb2_grpc.ExternalDataReaderStub(channel)

    # info from physical storage
    access_group_id = 0
    access_channel_ids = [0, 1, 2]
    access_identifier = ods_external_data_pb2.Identifier(url=access_file_url, parameters=access_file_parameters)

    # open bulk access
    access_handle = stub.Open(access_identifier)
    try:
        request = ods_external_data_pb2.ValuesRequest(
            handle=access_handle, group_id=access_group_id, channel_ids=access_channel_ids
        )

        # read first chunk
        request.start = 0
        request.limit = 3
        values = stub.GetValues(request)
        print(MessageToJson(values))

        # read second chunk
        request.start = 3
        request.limit = 10
        values = stub.GetValues(request)
        print(MessageToJson(values))

    finally:
        stub.Close(access_handle)
{
  "channels": [
    {
      "id": "0",
      "values": {
        "dataType": "DT_DOUBLE",
        "unitId": "0",
        "doubleArray": {
          "values": [
            0.0,
            17905500.0,
            30515300.0
          ]
        }
      }
    },
    {
      "id": "1",
      "values": {
        "dataType": "DT_LONGLONG",
        "unitId": "0",
        "longlongArray": {
          "values": [
            "1686082945335777300",
            "1686082945353682800",
            "1686082945366292600"
          ]
        }
      }
    },
    {
      "id": "2",
      "values": {
        "dataType": "DT_LONG",
        "unitId": "0",
        "longArray": {
          "values": [
            112,
            112,
            112
          ]
        }
      }
    }
  ]
}
{
  "channels": [
    {
      "id": "0",
      "values": {
        "dataType": "DT_DOUBLE",
        "unitId": "0",
        "doubleArray": {
          "values": [
            48317800.0,
            66109300.0,
            84173500.0,
            101965900.0,
            121611700.0,
            138016000.0,
            150423100.0,
            168052100.0,
            186278500.0,
            203702900.0
          ]
        }
      }
    },
    {
      "id": "1",
      "values": {
        "dataType": "DT_LONGLONG",
        "unitId": "0",
        "longlongArray": {
          "values": [
            "1686082945384095100",
            "1686082945401886600",
            "1686082945419950800",
            "1686082945437743200",
            "1686082945457389000",
            "1686082945473793300",
            "1686082945486200400",
            "1686082945503829400",
            "1686082945522055800",
            "1686082945539480200"
          ]
        }
      }
    },
    {
      "id": "2",
      "values": {
        "dataType": "DT_LONG",
        "unitId": "0",
        "longArray": {
          "values": [
            112,
            112,
            112,
            112,
            112,
            112,
            112,
            112,
            112,
            112
          ]
        }
      }
    }
  ]
}

License#

Copyright © 2024 Peak Solution GmbH

The training material in this repository is licensed under a Creative Commons BY-NC-SA 4.0 license. See LICENSE file for more information.