udmi

UDMI / Docs / Specs / Point Typing

Point Typing Specification

This specification defines how UDMI classifies telemetry and control points into Numeric, Multi-state, String, and Binary types based on the device’s site model (metadata.json), and how that classification governs the JSON payload structure of pointset messages (events, config, and state).


1. Overview and Classification Rules

Every point declared under pointset.points.<point_name> in a device’s metadata.json is deterministically classified into one of four mutually exclusive point types—Numeric, Multi-state, String, or Binary—based on the mutually exclusive units, values, and type fields:

Point Type Site Model Condition (pointset.points.<point_name>) Wire JSON Type (present_value & set_value) Valid Payload Examples Invalid Payload Examples
Numeric units is defined; values and type are omitted number (integer or floating-point) 21.5, 100, 0, -4.2 "21.5", true, "HIGH"
Multi-state values is defined; units and type are omitted string (raw value key in values) "0.0", "1.0", "1", "2" 0, 1.0, true, "OFF", "OCCUPIED"
String type is "string"; units and values are omitted string (arbitrary string literal) "v2.4.1", "NONE", "A1-04" 21.5, 100, true, false
Binary type is "boolean"; units and values are omitted boolean (true or false) true, false 0, 1, "true", "ON"
Invalid Two or more of units, values, and type are defined, or all three are omitted Validation Error N/A N/A
flowchart TD
    A["Point definition in metadata.json<br/>pointset.points.&lt;point_name&gt;"] --> B{"Is exactly one of 'units',<br/>'values', or 'type' defined?"}
    B -- No --> ERR["Validation Error:<br/>Exactly one of 'units', 'values', or 'type' must be defined"]
    B -- Yes --> C{"Is 'units' defined?"}
    C -- Yes --> NUM["Type: NUMERIC<br/>Wire Payload: JSON number"]
    C -- No --> D{"Is 'values' defined?"}
    D -- Yes --> MS["Type: MULTI-STATE<br/>Wire Payload: JSON string (key in 'values')"]
    D -- No --> E{"What is the value of 'type'?"}
    E -- "string" --> STR["Type: STRING<br/>Wire Payload: JSON string (literal)"]
    E -- "boolean" --> BIN["Type: BINARY<br/>Wire Payload: JSON boolean (true / false)"]

Mutual Exclusivity and Model Constraints

  1. Exact-One Requirement (Mutual Exclusivity): Every point definition in metadata.json MUST specify at most one and at least one of units, values, or type. Specifying two or more of these fields—or omitting all three—is a site model validation error.
  2. Field Definitions:
    • When units is present, it MUST be a non-empty string designating the unit of measure (or an explicit dimensionless unit designator such as "no-units").
    • When values is present, it MUST be a non-empty object mapping at least two raw device values to canonical state strings.
    • When type is present, it MUST be set to either "string" (designating a String point) or "boolean" (designating a Binary point).

2. Type Specifications

2.1 Numeric Points (units Defined)

A point is Numeric when pointset.points.<point_name>.units is present and both values and type are absent.

Site Model (metadata.json)

Wire Payloads


2.2 Multi-state Points (values Defined)

A point is Multi-state when pointset.points.<point_name>.values is present and both units and type are absent.

Site Model (metadata.json)

Wire Payloads


2.3 String Points (type: "string")

A point is String when pointset.points.<point_name>.type is set to "string" and both units and values are absent.

Site Model (metadata.json)

Wire Payloads


2.4 Binary Points (type: "boolean")

A point is Binary when pointset.points.<point_name>.type is set to "boolean" and both units and values are absent.

Site Model (metadata.json)

Wire Payloads


3. End-to-End Example

3.1 Site Model Definition (devices/AHU-1/metadata.json)

The following pointset block in metadata.json illustrates all four point types—including a continuous Numeric sensor, a dimensionless Numeric counter, a two-state Multi-state command, a four-state Multi-state mode, a String literal point, and two Binary status/command points:

{
  "version": "1.5.7",
  "timestamp": "2026-01-01T00:00:00Z",
  "pointset": {
    "points": {
      "supply_air_temperature_sensor": {
        "units": "degrees-celsius",
        "ref": "analog_input_1",
        "baseline_value": 21.5,
        "baseline_tolerance": 2.0
      },
      "cooling_request_count": {
        "units": "no-units",
        "ref": "analog_value_4"
      },
      "supply_fan_run_command": {
        "writable": true,
        "ref": "digital_output_2",
        "values": {
          "0.0": "OFF",
          "1.0": "ON"
        },
        "baseline_value": "1.0"
      },
      "occupancy_mode": {
        "writable": true,
        "ref": "multistate_value_1",
        "values": {
          "1": "OCCUPIED",
          "2": "UNOCCUPIED",
          "3": "STANDBY",
          "4": "BYPASS"
        },
        "baseline_value": "1"
      },
      "active_fault_code": {
        "type": "string",
        "ref": "characterstring_value_1",
        "baseline_value": "NONE"
      },
      "filter_alarm_pressure_status": {
        "type": "boolean",
        "ref": "binary_input_11",
        "baseline_value": false
      },
      "damper_isolation_enable": {
        "type": "boolean",
        "writable": true,
        "ref": "binary_output_5",
        "baseline_value": true
      }
    }
  }
}

3.2 Resulting Config Message (config -> pointset)

When the cloud configures the device (including writeback set_value entries derived from baseline_value for writable points), the generated config.pointset block is:

{
  "sample_rate_sec": 300,
  "points": {
    "supply_air_temperature_sensor": {
      "ref": "analog_input_1",
      "units": "degrees-celsius"
    },
    "cooling_request_count": {
      "ref": "analog_value_4",
      "units": "no-units"
    },
    "supply_fan_run_command": {
      "ref": "digital_output_2",
      "set_value": "1.0"
    },
    "occupancy_mode": {
      "ref": "multistate_value_1",
      "set_value": "1"
    },
    "active_fault_code": {
      "ref": "characterstring_value_1"
    },
    "filter_alarm_pressure_status": {
      "ref": "binary_input_11"
    },
    "damper_isolation_enable": {
      "ref": "binary_output_5",
      "set_value": true
    }
  }
}

3.3 Resulting Pointset Event Payload (events/pointset)

The client publishes the corresponding events/pointset telemetry message with each point’s present_value formatted according to its resolved type:

{
  "version": "1.5.7",
  "timestamp": "2026-01-01T00:05:00Z",
  "points": {
    "supply_air_temperature_sensor": {
      "present_value": 21.4
    },
    "cooling_request_count": {
      "present_value": 3
    },
    "supply_fan_run_command": {
      "present_value": "1.0"
    },
    "occupancy_mode": {
      "present_value": "1"
    },
    "active_fault_code": {
      "present_value": "NONE"
    },
    "filter_alarm_pressure_status": {
      "present_value": false
    },
    "damper_isolation_enable": {
      "present_value": true
    }
  }
}