Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: SDF Enum Type #2

Closed
asoloway64 opened this issue Aug 10, 2020 · 16 comments · Fixed by #8
Closed

Feature Request: SDF Enum Type #2

asoloway64 opened this issue Aug 10, 2020 · 16 comments · Fixed by #8

Comments

@asoloway64
Copy link

User-defined enumerated data type is a beneficial feature. SDF should provide the ability for a user to define a mapping between a supported fundamental data type (integer, string, etc) and an associated value.

For example, Operational Mode for my object:
0 => "Off"
1 => "On"
2 => "Power-Save"
3 => "Suspended"
4 => "Automatic"

@WAvdBeek
Copy link
Contributor

actually I am against that.
the integer values are used as transport binding in this way.
the real semantic values are "Off"/"On" etc.

@asoloway64
Copy link
Author

How can you create gaps to have specified ranges?
0-9: Pre-defined values set 1 (0=Off, 1=On)
10-19: Pre-defined values set 2 (10=Power-save, 11=Automatic)
20-29: Vendor-defined values (20=Suspended, for vendor 1)

@WAvdBeek
Copy link
Contributor

The whole issue is that one should not do these things. if this is something that an org needs, then they should capture that in a mapping file. the only thing interesting in the example above are
On, off, power-save,automatic, suspended-vendor-1

@mjkoster
Copy link
Collaborator

mjkoster commented Aug 11, 2020

The problem I would like to solve with SDF enums requires a good semantic anchor (URI) for each defined element of an enum, with a description and other potential extension points, including numeric code mappings. For number code mapping we propose an external mapping file that adds additional qualities to an element in the SDF file, but there may also be extension points added in the SDF file itself. Elements may also contain value constraints but the better practice is probably to use a mapping file. Default with override is another design option.

I propose a pattern of identifier definition similar to the one we already use for sdfAction, sdfProperty, sdfEvent, etc.

"sdfProperty": {
  "state": {
    "sdfEnum": {
      "on": {
        "description": "activated state, or powered state",
        "label": "On"
      },
      "off": {
        "description": "deactivated state, or non-powered state",
        "label": "Off"
      }
   }

The URI fragment identifier looks like:

#/sdfProperty/state/sdfEnum/on

and a mapping file entry would look like:

"#/sdfProperty/state/sdfEnum/on": {
  "type": "integer",
  "const": 1
},

Of course, the extension point might be in the SDF file with some specific constraints, but some generality is lost this way:

"sdfProperty": {
  "state": {
    "sdfEnum": {
      "on": {
        "description": "activated state, or powered state",
        "label": "On",
        "anyOf": {
          "type": number",
          "const": 1
        },
        {
          "type": string",
          "const": "on"
        },
        {
          "type": boolean"
          "const": true
        }
      },
      "off": {
        "description": "deactivated state, or non-powered state",
        "label": "Off",
        "anyOf": {
          "type": number",
          "const":0
        },
        {
          "type": string",
          "const": "off"
        },
        {
          "type": boolean"
          "const": false
        }
      },
      }
   }

@WAvdBeek
Copy link
Contributor

the current JSON schema mechanism is:

"sdfProperty"
"myname":
{
"type": "string",
enum: [ "value1", "value2" ...]

hence a URI to a value can be

#/sdfProperty/myname/value1
where the last component is the actual string.
so we do not need to separate out the enum in a JSON object.

not sure if we need to have extensive descriptions for each enum value. the context of the enum values itself should be clear from the description of the property (e.g. the description of "myname")

@WAvdBeek
Copy link
Contributor

I am very much against mixing and matching integers, numbers and strings in a single enumeration, e.g. a enumeration can be only of a single type.
I thought we already agreed that if that would occur we should have a rethink about the model itself, not about the language.

@akeranen
Copy link
Collaborator

akeranen commented Nov 2, 2020

Being able to attach a detailed description is a must so the JSON schema enum is not sufficient here. Label could be omitted if it's identical to the identifier (but that doesn't always work due to special characters). The on-the-wire value is up to the ecosystem but I think it would be highly useful to provide Integer values for each enum to assist automating the mapping. Otherwise every ecosystem that has integer-like mapping would need to define that individually. Ecosystems that don't have use for the integer can simply ignore that.

@mjkoster
Copy link
Collaborator

mjkoster commented Nov 2, 2020

I have assumed that issues we discovered in assigning ID numbers within OneDM extended to every definition point, including enum elements. I think the elevator version is: ecosystems that use ID numbers have their schemes that we can't pre-define compatibility with all of them, and ecosystems that don't use ID numbers prefer to not be required to generate them. Hence mapping files, and the reason I included a mapping file example above in my comments.

@akeranen
Copy link
Collaborator

For the objects and resources the IDs are not likely to be identical across ecosystems so there the "oneDM IDs" would be less useful, but for enums I think the case is quite different. Because the scope is smaller and there aren't many sensible numbering schemes, there's a good chance all ecosystems with numeric enums would use the same number. And ecosystems would not need to generate any of the IDs, those can be auto-assigned. Perhaps, if the enum construct is an array, that's all we need since the array index would provide that number in a consistent way.

@mjkoster
Copy link
Collaborator

mjkoster commented Nov 17, 2020

Enum items have the mapping issue; they have already assigned numeric codes to enum items in various SDOs.

@mjkoster
Copy link
Collaborator

I just refactored a number of enums and it seems easy to convert to/from regular JSON schema enums:

      "sdfData": {
        "GenericOnOffData": {
          "description": "the on/off state property",
          "enum": [
            "Off", 
            "On"
          ]
        }
      "sdfData": {
        "GenericOnOffData": {
          "description": "the on/off state property, use a mapping file for encoded values",
          "sdfEnum": {
            "Off": {}, 
            "On": {}
          }
        }

If we want to add default ID numbers to enums we could

      "sdfData": {
        "GenericOnOffData": {
          "description": "the on/off state property, use a mapping file to override default encoded values",
          "sdfEnum": {
            "Off": { "default": 0 }, 
            "On": { "default": 1 }
          }
        }

We can always override the default in a mapping file:

"sdfMap": {
  "#/sdfData/GenericOnOffData/sdfEnum/Off": { "const": 127 },
  "#/sdfData/GenericOnOffData/sdfEnum/On": { "const": 255 }
}

@cabo
Copy link
Member

cabo commented Nov 17, 2020

Here is what I will propose later today:

"sdfProperty": {
  "state": {
    "choice": {
      "on": {
        "description": "activated state, or powered state"
      },
      "off": {
        "description": "deactivated state, or non-powered state"
      }
   }

and

"sdfProperty": {
  "StartUpCurrentLevel": {
    "choice": {
      “ActualSetting”: {
        "type": "number",
        "minimum": 1,
        "maximum": 254
      },
      "MinimumDeviceValuePermitted": {
        "const": 0
      },
      "SetToPreviousValue": {
        "const": 255
      }
    }
  }
}

I'm not sure why we need a "default" -- we can set values at the information model level and map to different values at the mapping level.

@cabo
Copy link
Member

cabo commented Nov 17, 2020

The point here is that there is no difference between enum and anyOf -- both should have labels (that can replace the enum text strings) plus any description, semantic tag, value ranges, etc. as needed.

@mjkoster
Copy link
Collaborator

mjkoster commented Nov 17, 2020

Yes, the multiple choice pattern works for both use cases.

@WAvdBeek
Copy link
Contributor

frankly, I do not like both solutions.
I think we should stick to the standard enum as defined by JSON schema.
we can add new qualities by having a new section in sdf that describes more qualities of the enum value itself.

enum "blah" : "value1, value2"

sdEnum "blah:value1" : { "my additional quality1": "x", }

@mjkoster
Copy link
Collaborator

mjkoster commented Dec 12, 2020

Here is where the asdf mailing list email discussion on this topic is currently, proposing to use "sdfAny" as a way to create semantically stable JSON pointers to enum items that map 1-1 to the JSON-schema.org simple enum items.

If we can agree on this pattern, I believe we could meet everyone's needs :

"sdfData": {
    "SwitchState": {
      "enum": [
        "on",
        "off"
      ],
      “sdfAny": {
        "on": {
          "label": "On",
          "description": "The powered or functionally active state",
          "default": "true"
        },
        "off": {
          "label": "Off",
          "description": "The un-powered or functionally inactive state",
          "default": "false"
        }
      }

@cabo cabo mentioned this issue Dec 14, 2020
@cabo cabo linked a pull request Jan 11, 2021 that will close this issue
@cabo cabo closed this as completed in #8 Jan 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants