Azure / opendigitaltwins-dtdl

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

Array support for components? #117

Open lindacmsheard opened 3 years ago

lindacmsheard commented 3 years ago

I'm having trouble understanding the Array documentation here https://github.com/Azure/opendigitaltwins-dtdl/blob/master/DTDL/v2/dtdlv2.md#array

I'd like to define an array of components of the same schema.

contents : [
{},{}... #other props
        {
            "@type": "Component",
            "name": "bins",
            "schema": {
                "@type": "Array",
                "elementSchema": "dtmi:my:twin:model:collection_point:bin;2"
            }
        }
]

--> HttpResponseError: (DTDLParserError) None of the models in this request could be created due to a problem with one or more models: dtmi:my:twin:model:collection_point;2 has 'contents' value with name 'bins' whose property 'schema' requires an identifer but none provided. Add an '@id' property whose value is a string that conforms to the DTMI syntax -- see https://github.com/Azure/digital-twin-model-identifier.. See model documentation(http://aka.ms/ADTv2Models) for supported format. Code: DTDLParserError

Things tried:

I've tried to follow the error resolution given by adding an id property to the schema. This then raises an error that @type must be Interface - while the array docs say that must be @Array.

        {
            "@type": "Component",
            "name": "bins",
            "schema": {
                "@type": "Array",
                "@id":"dtmi:my:twin:model:collection_point:bins;2",
                "elementSchema": "dtmi:my:twin:model:collection_point:bin;2"
            }
        }

--> HttpResponseError: (DTDLParserError) None of the models in this request could be created due to a problem with one or more models: dtmi:my:twin:model:collection_point;2 has 'contents' value with name 'bins' whose property 'schema' has value dtmi:defra:iot:waste_flows:collection_point:bins;2 that does not have @type of Interface. Provide a value for property 'schema' with @type Interface.. See model documentation(http://aka.ms/ADTv2Models) for supported format. Code: DTDLParserError

Can you clarify if arrays of components are supported, or if not, how to go about modelling objects with a variable number of components of the same type?

briancr-ms commented 3 years ago

Thanks for your question.

Arrays of components are not supported in DTDL. The elementSchema of an array must be a primitive or complex schema (but not an interface). In general DTDL's data description language (primitive schemas and complex schemas) is for defining data elements. Behavior (telemetry, properties, commands, and relationships--and including those via a component) is defined in interfaces.

However, I've heard other feedback that arrays of components could be useful. Can you share any more details about your use case?

Lastly, I can see that the parser's error message is not very helpful here. I'll forward that to our parser team so they can look at ways to improve this.

packnologyusa commented 2 years ago

Hi @briancr-ms I noticed that @lindacmsheard didn't respond here, but I would like to add a use case. Many machines will have a configuration that includes 1 to N instances of a component, and often the number of instances will be configurable per machine instance.

For a concrete example that I'm familiar with, a fruit grading machine can have 1 or more lanes conveying the fruit across the machine. The customer (fruit packing plant) will purchase a machine with the appropriate number of lanes to handle the throughput. A lane does not exist on its own without the machine, and the machine must have at least 1 lane. A lane might also have properties and telemetry of its own, but the model would be the same for all lanes and the telemetry values would usually be aggregated as a total for the machine. The largest machine I have seen has 70 lanes.

At the moment, in DTDL the only way to model a lane in this context would be to either: 1) create a separate machine model for each possible lane count configuration with the correct number of lane components, or 2) create a standalone lane model, create a twin instance for each lane for a specific machine configuration, and then create relationships between the lane and the machine it is part of. Option 1 would bloat the models list, Option 2 would bloat the twin graph.

Providing the ability to configure a machine twin based on N instances of a component (e.g. by adding components to a components array) would solve this problem and make DTDL much more flexible for these common industrial scenarios.

Thanks, Greg

briancr-ms commented 2 years ago

Thanks for the concrete example, @packnology, this is very helpful. As you noted, a separate twin for each lane is a possible solution, but I can see that having the lanes as Components would be even better because, as you noted, the lifetime of each lane is tied to the lifetime of the fruit grading machine that is made up of the lanes.