Azure / opendigitaltwins-dtdl

Digital Twins Definition Language
Creative Commons Attribution 4.0 International
481 stars 164 forks source link

Can't add a relation and i really can't figure out why #167

Closed ruthoferroman closed 1 year ago

ruthoferroman commented 1 year ago

I've ran into a problem, which is really confusing me.

I have a model dtmi:AutomationApps:SubPlants:HeatRecoveries:SP_HeatRecovery;1 which extends the dtmi:AutomationApps:SubPlants:SubPlant;1. In the dtmi:AutomationApps:SubPlants:SubPlant;1 i have declared the following relationship:

{
      "@type": "Relationship",
      "name": "ContainedIn",
      "displayName": {
        "en": "ContainedIn"
      },
      "description": {
        "en": "An App is contained in ONE other App (used for hirarchy). Inverse of: Contains"
      },
      "target": "dtmi:AutomationApps:Plants:Plant;1"
    },

Now i want to add a ContainedIn relation to a twin of dtmi:AutomationApps:Plants:AirHandlingUnits:P_AirHandlingUnit;1 which extends the dtmi:AutomationApps:Plants:Plant;1, but i always get an error Twin relationship does not align with the model. Please ensure that the relationship is in alignment with the model

All Models are V2.

jrdouceur commented 1 year ago

If I'm reading this right, you are trying to add a Relationship instance to a twin of dtmi:AutomationApps:Plants:AirHandlingUnits:P_AirHandlingUnit;1, but you declared the Relationship in model dtmi:AutomationApps:SubPlants:SubPlant;1. You need to add the Relationship edge to a twin of the model in which you have declared the Relationship, not to a twin of a model that is the target of the relationship.

ruthoferroman commented 1 year ago

@jrdouceur No, i want to add a relationship to a instance of dtmi:AutomationApps:SubPlants:HeatRecoveries:SP_HeatRecovery;1 to target a instance of dtmi:AutomationApps:Plants:AirHandlingUnits:P_AirHandlingUnit;1

simplified: dtmi:AutomationApps:SubPlants:HeatRecoveries:SP_HeatRecovery;1 ---> ContainedIn --> dtmi:AutomationApps:Plants:AirHandlingUnits:P_AirHandlingUnit;1

jrdouceur commented 1 year ago

What you are attempting seems reasonable to me, but my knowledge of ADT is not very strong, and I know I have had confusion regarding the covariance/contravariance of Relationship targets. I'm trying to follow up with more knowledgeable folks about this. I'll let you know what I learn.

ruthoferroman commented 1 year ago

@jrdouceur thanks!

It seems like there is an issue with all models that extend the plant model.

{
  "@id": "dtmi:AutomationApps:Plants:Plant;1",
  "@type": "Interface",
  "@context": "dtmi:dtdl:context;2",
  "displayName": "Plant",
  "contents": [
    {
      "@type": "Relationship",
      "name": "Contains",
      "displayName": {
        "en": "Contains"
      },
      "description": {
        "en": "An App contains another Apps (used for hirarchy). Inverse of: ContainedIn"
      }
    },
    {
      "@type": "Relationship",
      "name": "ContainedIn",
      "displayName": {
        "en": "ContainedIn"
      },
      "description": {
        "en": "An App is contained in ONE other App (used for hirarchy). Inverse of: Contains"
      },
      "target": "dtmi:AutomationApps:Spaces:Space;1"
    },
    {
      "@type": "Relationship",
      "name": "Feeds",
      "displayName": {
        "en": "Feeds"
      },
      "description": {
        "en": "Indicates that a given equipment is feeding something to another equipment or space, like electricity, water or air. For example, an AHU equipment feeds air to a VAV equipment. Inverse of: IsFedBy"
      },
      "target": "dtmi:AutomationApps:Plants:Plant;1"
    },
    {
      "@type": "Relationship",
      "name": "IsFedBy",
      "displayName": {
        "en": "IsFedBy"
      },
      "description": {
        "en": "Indicates that a given equipment is fed by something to another equipment or space, like electricity, water or air. For example, an AHU equipment feeds air to a VAV equipment. Inverse of: Feeds"
      },
      "target": "dtmi:AutomationApps:Plants:Plant;1"
    }    
  ],
  "extends": "dtmi:AutomationApps:Abstractions:AutomationAppBase;1"
}

dtmi:AutomationApps:Plants:AirHandlingUnits:P_AirHandlingUnit;1

{
  "@id": "dtmi:AutomationApps:Plants:AirHandlingUnits:P_AirHandlingUnit;1",
  "@type": "Interface",
  "@context": "dtmi:dtdl:context;2",
  "displayName": "P_AirHandlingUnit",
  "contents": [
    {
      "@type": "Property",
      "name": "IsOn",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "IsMan",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "ErrSum",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "ShowTrendPanels",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "ShowEfficiency",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "ShowEfficiencyDemo",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "ShowSupplyDuct",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "ShowExhaustDuct",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "ShowFans",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "ShowHeating",
      "schema": "boolean"
    },
    {
      "@type": "Property",
      "name": "ShowCooling",
      "schema": "boolean"
    }
  ],
  "extends": "dtmi:AutomationApps:Plants:Plant;1"
}
jrdouceur commented 1 year ago

I have received clarification from ADT on this issue. When computing type compatibility for a Relationship instance, ADT does not consider values of the "extends" property at all. In the case above, the service is complaining because the instance target has a type of dtmi:...:P_AirHandlingUnit;1, but the modeled Relationship target type is dtmi:...:Plant;1, which is not the same type. It is true that dtmi:...:P_AirHandlingUnit;1 extends dtmi:...:Plant;1, and therefore an instance of dtmi:...:P_AirHandlingUnit;1 is (in some sense) an instance of dtmi:...:Plant;1; however, this is not considered when evaluating Relationship instances. (The type does not have to be strictly exact, insofar as the version-number suffix is ignored when checking the type, but this is probably not helpful for your use case.)

You have a few options here, depending on what changes you might be willing to live with in the type hierarchy and in the specification of the ContainedIn Relationship. The simplest change is to remove the target property from the Relationship definition, which essentially makes it a wildcard. Unfortunately, this makes your model less expressive than you might want it to be, but it will avoid the error you are running into now. You could partially offset this by augmenting the description or adding a comment to indicate that the target is expected to be a subtype of dtmi:AutomationApps:Plants:Plant;1.

ruthoferroman commented 1 year ago

Ok, thanks for your illustartion.

I'm just confused how the for example Space model from the Real Estate Ontology can work see https://github.com/Azure/opendigitaltwins-building/blob/master/Ontology/Space/Space.json. Many models are extended from the Space model and there are several relationsships in the Space model targeting to the Space model as well.

Is it because they use DTDL V3?

ruthoferroman commented 1 year ago

Seems like the problem was something diffferent.

I've figured out that the Twins of dtmi:AutomationApps:SubPlants:HeatRecoveries:SP_HeatRecovery;1 causing the problems even didn't show up when i did a query like and IS_OF_MODEL('dtmi:AutomationApps:SubPlants:SubPlant;1')

So I changed a single property on that Twins and as soon I did it everything worked fine.

Update: and I can see the model as is is working fine. Event the relation declarations in dtmi:AutomationApps:Plants:Plant;1 model with specific targets

jrdouceur commented 1 year ago

Well, that's fascinating. I'm glad your model and system are working, but I'm rather confused by the behavior. I'll take this back to ADT for further clarification.