Table Of Contents

Previous topic

Vendor

Next topic

Constructed Data Types

This Page

Primitive Data Types

The standard defines primitive data types to describe most of the components of objects and protocol data units.

Null

This is a special class that holds a unique value to signify special values in objects and special values for APDU’s:

:Null
    rdf:type owl:Class ;
    owl:equivalentClass
          [ rdf:type owl:Class ;
            owl:oneOf (null:null)
          ] .

This class has only one named individual:

null:null
    rdf:type :Null , owl:NamedIndividual .

Boolean

Boolean values are pretty straight forward:

:Boolean
    rdf:type rdfs:Datatype ;
    owl:equivalentClass xsd:boolean .

Unsigned

Most of the unsigned values used in the standard have no specific value limit so the ontology specifies them as long:

:Unsigned
    rdf:type rdfs:Datatype ;
    owl:equivalentClass xsd:unsignedLong .

Integer

Integers are very similar to unsigned values:

:Integer
    rdf:type rdfs:Datatype ;
    owl:equivalentClass xsd:long .

Real

This datatype is identical to the IEEE single precision floating point:

:Real
    rdf:type rdfs:Datatype ;
    owl:equivalentClass xsd:float .

Double

This datatype is identical to the IEEE double precision floating point:

:Double
    rdf:type rdfs:Datatype ;
    owl:equivalentClass xsd:double .

OctetString

Octet strings are used to transfer blobs of information that is not otherwise specified as structured content:

:OctetString
    rdf:type rdfs:Datatype ;
    owl:equivalentClass xsd:base64Binary .

CharacterString

Character strings are This is a long line of text:

:CharacterString
    rdf:type rdfs:Datatype ;
    owl:equivalentClass xsd:string .

Character strings have an “encoding” when it appears in an APDU, and some devices have restrictions on what encoding formats they support.

BitString

Here is an ASN.1 example of a bit string:

BACnetEventTransitionBits ::= BIT STRING {
    to-offnormal  (0),
    to-fault      (1),
    to-normal     (2)
    }

Bit strings are packed arrays of named bits, this ontology uses rdf:Bag to note the bit definitions can be unordered:

:BitString
    rdf:type owl:Class ;
    rdfs:subClassOf rdf:Bag .

The bag contains bits, each of which has a specific nominal value:

:Bit rdf:type owl:Class .

bit:nominal
    rdf:type owl:DatatypeProperty , owl:FunctionalProperty ;
    rdfs:domain :Bit ;
    rdfs:range xsd:nonNegativeInteger .

How can the ontology restrict the “bag” contents to only contain named individual bits that are a subclass of BitString?

Enumeration

This is the ANS.1 definition of an enumeration:

BACnetFileAccessMethod ::= ENUMERATED {
    record-access     (0),
    stream-access     (1)
    }

The Enumeration class is a way to group all labeled values together. There are two types of enumerations, those defined in the standard and those that can be defined by vendors with their own names and values:

:Enumeration
    rdf:type owl:Class ;
    owl:disjointUnionOf (:ProprietaryEnumeration :StandardEnumeration) .

Some enumerations (see below) can have additional values added to them by vendors which are called extended enumerations:

:ExtendedEnumeration
    rdf:type owl:Class ;
    rdfs:subClassOf :StandardEnumeration .

Every enumerated value is a named individual object that has a nominal value:

enum:nominal
    rdf:type owl:DatatypeProperty , owl:FunctionalProperty ;
    rdfs:domain :Enumerated ;
    rdfs:range xsd:nonNegativeInteger .

Enumerations that are defined by a vendor have a relationship to the Vendor object, and this applies to both extended enumerations and proprietary enumerations:

enum:vendor
    rdf:type owl:FunctionalProperty , owl:ObjectProperty ;
    rdfs:domain
          [ rdf:type owl:Class ;
            owl:unionOf (:ExtendedEnumeration :ProprietaryEnumeration)
          ] ;
    rdfs:range :Vendor .

PropertyIdentifier

This is an example of an extended enumeration definition.

Property identifiers are used to describe properties or components of objects. Vendors can extend objects by adding their own properties which are distinguished from those in the standard by using values above those reserved to ASHRAE.

The standard defines some property identifiers:

:PropertyIdentifier
    rdf:type owl:Class ;
    rdfs:subClassOf :StandardEnumeration ;
    owl:equivalentClass
        [ rdf:type owl:Class ;
          owl:oneOf (pi:ackedTransitions pi:ackRequired pi:action ... )
        ] .

Because the PropertyIdentifier class is restricted to the named individuals, there is a subclass for those that the vendor wants to define. This is a subclass so that every place where a PropertyIdentifier is required, an ExtendedPropertyIdentifier can be used. The upper bound is the maximum value the enumeration can have so vendors know an appropriate integer size (short, long, etc.) in their implementation:

:ExtendedPropertyIdentifier
    rdf:type owl:Class ;
    rdfs:subClassOf :PropertyIdentifier , :ExtendedEnumeration ;
    rdfs:subClassOf
        [ rdf:type owl:Restriction ;
          owl:onProperty enum:nominal ;
          owl:someValuesFrom
              [ rdf:type rdfs:Datatype ;
                owl:onDatatype xsd:nonNegativeInteger ;
                owl:withRestrictions
                    ( [ xsd:minInclusive 512 ]
                      [ xsd:maxInclusive 4194303 ]
                    )
              ]
        ] .

The property identifiers that are defined in the standard are defined in the ontology as named individuals:

pi:ackedTransitions
    rdf:type :PropertyIdentifier , owl:NamedIndividual ;
    enum:nominal 0 .
pi:ackRequired
    rdf:type :PropertyIdentifier , owl:NamedIndividual ;
    enum:nominal 1 .
pi:action
    rdf:type :PropertyIdentifier , owl:NamedIndividual ;
    enum:nominal 2 .

I have a suspicion that I can’t restrict the standard enumerations to some named individuals and yet open up a subclass to vendor values.

Date

The date value in the standard has four parts; year, month, day and day-of-week. Each of these values are unsigned octets that can have the value 255 meaning “wild card” value. The ontology defines this as a patterned string of four components similar to other date formats, but cannot use standard date formats because of the wild card value:

:Date
    rdf:type rdfs:Datatype ;
    owl:equivalentClass
          [ rdf:type rdfs:Datatype ;
            owl:onDatatype xsd:string ;
            owl:withRestrictions
                    ([ xsd:pattern "([0-9]{4}|[*])-([0-9]{2}|[*])-([0-9]{2}|[*])-([0-9]{2}|[*])"
                      ])
          ] .

Time

The time value is very similar to the date format with four parts; hours, minutes, seconds, and hundredths. It can also contian wild card values:

:Time
    rdf:type rdfs:Datatype ;
    owl:equivalentClass
          [ rdf:type rdfs:Datatype ;
            owl:onDatatype xsd:string ;
            owl:withRestrictions
                    ([ xsd:pattern "([0-9]{2}|[*]):([0-9]{2}|[*]):([0-9]{2}|[*])[.]([0-9]{2}|[*])"
                      ])
          ] .

ObjectIdentifier

Every object in the standard has a unique object identifier, a 32-bit packed value which contains a 10-bit object type and 22-bit instances number:

:ObjectIdentifier
    rdf:type owl:Class .

Rather than specifying the object type as an unsigned integer, the ontology defines it as a relationship to a named individual of type ObjectIdentifier, which is itself an enumerated value:

oid:type
    rdf:type owl:FunctionalProperty , owl:ObjectProperty ;
    rdfs:domain :ObjectIdentifier ;
    rdfs:range :ObjectType .

The instance number is just a non-negative integer with a limited range:

oid:instance
    rdf:type owl:DatatypeProperty , owl:FunctionalProperty ;
    rdfs:domain :ObjectIdentifier ;
    rdfs:range
          [ rdf:type rdfs:Datatype ;
            owl:onDatatype xsd:nonNegativeInteger ;
            owl:withRestrictions
                    ([ xsd:minInclusive 0
                      ] [ xsd:maxInclusive 4194302
                      ])
          ] .

ObjectName

Most of the character strings in the standard can be empty, but object names must have at least one character:

:ObjectName
    rdf:type rdfs:Datatype ;
    owl:equivalentClass
          [ rdf:type rdfs:Datatype ;
            owl:onDatatype xsd:string ;
            owl:withRestrictions
                    ([ xsd:minLength 1
                      ])
          ] .

Assuming there is a Device class, and that devices contain objects, how can the ontology specify that the object name for each object must be unique within the device?