Azure / opendigitaltwins-dtdl

Digital Twins Definition Language
Creative Commons Attribution 4.0 International
466 stars 160 forks source link

Configuration cannot be mapped with dtdl #116

Closed feckert closed 2 years ago

feckert commented 3 years ago

I am currently writing a dtdl for my device. This is a network device. I want to create rules for the firewall via the IoT-Hub. I wanted to use the properties for this. Somehow I can't find a sample that explains it properly! All properties are defined at the top level, after the "contents". I also saw that apparently the property type does not support arrays in schema! Now, unfortunately, it is not clear to me how I should map this.

I would have imagined it like this (this is not a valid dtdl description):

{
  "@context": "dtmi:dtdl:context;2",
  "@id": "dtmi:com:example:NetworkDevice;1",
  "@type": "Interface",
  "displayName": "Thermostat",
  "description": "Reports current temperature and provides desired temperature control.",
  "contents": [
    {
      "@type": "Property",
      "name": "Forwarding",
      "displayName": "Firewall Forwarding",
      "description": "Allows to edit remotly the firewall forwardings.",
      "schema": {
        "@type": "Array",
        "elementSchema" : {
          "@type": "Object",
          "fields": [
            {
              "name": "section",
              "displayName": "Section",
              "description": "Section name",
              "schema": "string",
              "writable": true
            },
            {
              "name": "SourceIP",
              "displayName": "Source IP",
              "description": "Source IP of the RSU for the port forwarding",
              "schema": "string",
                "writable": true
            },
            {
              "name": "SourcePort",
              "displayName": "Source port",
              "description": "Source port for the port forwarding.",
              "schema": "string",
                "writable": true
            },
            {
              "name": "DestinationIP",
              "displayName": "Destination IP",
              "description": "Destination IP e.g. IP of the FPA.",
              "schema": "string",
                "writable": true
            },
            {
              "name": "DestinationPort",
              "displayName": "Destination port",
              "description": "Destination port for the port forwarding.",
              "schema": "string",
                "writable": true
            }
          ]
        }
      }
    }
  ]
}

I want to create a firewall rule, for example, via a command, and then edit this via the property. The question I have is whether the property is intended for this purpose at all or should I also use the command to create it with the values, but then I can no longer change the properties afterwards. The configurations are saved on the unit.

Maybe you can help me further. I am at a bit of a loss as to how to implement this now?

briancr-ms commented 3 years ago

Hi, thanks for your question about this.

Yes, in general, a Property is intended for device (or digital twin) state. In particular, for devices that are connected to IoT Hub, a Property is used to synchronize state between the device and IoT Hub. For example, a cloud service can update a writable Property and, when a device connects to IoT Hub, it can get the latest updates (desired property values) from the cloud.

You're also correct that currently arrays are not supported for Properties. This is a limitation we are working on correcting.

In the meantime, there are a couple approaches that you can take and still get the benefits of Properties:

  1. If the maximum number of elements in your Array is known and small, you can create a complex Object with a field for each element ("element1", "element2", etc.). Since all fields are optional, fields without values are not stored or transmitted.
  2. If the number of elements in your array is unknown or large, then you can simulate an Array with a Map using keys like array indexes ("0", "1", etc.). This approach requires a bit more code to manage the Map like an Array.