Reading and Writing a Datapoint Value

You can read or write the present value of a datapoint using IAP/MQ as well as IAP/REST. The present value conforms to the type specification for the specific datapoint.

To get a list of installed devices and their datapoints, refer to Obtaining a List of Installed Devices

Writing datapoint values using IAP/MQ directly maps a publish method to a topic that describes a specific datapoint.  The process of reading a datapoint through IAP/MQ requires considering the following details:

  • One time reads of a single datapoint
  • Continuous monitoring of datapoint value changes

Refer to the following for reading and writing datapoints with SmartServer 2.8 and higher:

  • Value - this is the value that is read from the device or written to the device (this non-localized value is some times called IAP value)
  • Localized value - a localization formula is used to transform the IAP value to and from a localized value
    • Localized values are used to show region values (so if the IAP value is in degrees Celsius you can configure the datapoint to show a localized value as degress Fahrenheit)
    • Localized values can be used to show datapoint precision (number of decimal places like x.xx)
    • If a localization formula (CMS Datapoint Properties Widget) is not assigned to a datapoint then the localized value is the same value as the IAP value.
  • Presets - a preset value of null means no matching preset, a non null value means preset match. For example a preset value of "ON" may mean a IAP value of "true".
  • Priority Overrides - 1 (highest) thru 16 (lowest), and Normal (17).
    • You can only change values that are the same or higher priority then the current datapoint priority, if writing at a lower priority the priority array will change but the current value is not changed. 
    • To see the datapoint priority array then just GET all the properties for the datapoint.  That is, priority array is not provided when getting just the datapoint value
    • Priorities are written to BACnet Edge devices but not to LON or MODBUS edge devices

Notes:

  • The preset value, IAP value and localized value are stored for each datapoint.
  • Only IAP values are sent to the edge devices.  Presets and localized values are used internally to the SmartServer. 
    • When writing to a IAP value, preset value, or localized value, the other value properties are updated based on configuration. In all cases, it is the IAP value that gets sent to the edge devices. 
  • Preset value, localized value and IAP value are all available when you get the current datapoint value.
  • When writing to datapoints, you need to write using of the following preset value, localized value or IAP value, and decide whether you write with a priority or no priority.  When priority is not specified, then the write uses normal priority (17).
  • Presets and localization can be configured in the Datapoint Properties widget, DLA file or through REST or MQTT APIs.

Programming Examples

This section contains the following examples:

IAP/MQ Datapoint Value Subscription and Reporting

Datapoint values are subscribed to and reported in the following topic, and updates for all datapoints associated with the block will be received. (Topics and blocks are described in Interface Blocks and IAP/MQ Topic Syntax.)

You will need to connect to the message broker, then subscribe to the specific datapoint, and if necessary, set the monitor rate to a non-zero value.  For information on configuring monitor rates, see Configuring Periodic Monitoring for a Datapoint.

glp/0/{SID}/fb/dev/{Edge_Protocol_ID}/{Handle}/if/{block_name}/{block_index}                                                      

Topic Examples


            glp/0/{SID}/{fb|rq}/dev/lon/123/if/light/1

            glp/0/{SID}/{fb|rq}/dev/lon/123/if/occupancy/0        

            glp/0/{SID}/{fb|rq}/dev/lon/123/if/temperature/indoor

            glp/0/{SID}/{fb|rq}/dev/lon/123/if/temperature/outdoor     

            glp/0/{SID}/{fb|rq}/dev/lon/d.1/if/light/1

                                                                                                                                                                                                                                                                   

Node.js Example


Connect to broker in node.js:

    let mySmartServerIoT = 'mqtt//192.168.123.228:1883';

    let mqttClient = mqtt.connect (mySmartServerIoT);

Subscription to updates in node.js:

    let Subscribe = 'glp/0/' + SID  + '/fb/dev/lon/' + MyDeviceHandle  + '/if/LightSensor/0';    // specify the datapoint's feedback channel                 
    mqttClient.subscribe (Subscribe);                                                                                          // subscribe to listen for NV updates;

Publish to set monitor rate to non zero to get updates in node.js:

    let topic = 'glp/0/' + SID + '/rq/dev/lon/' + MyDeviceHandle  + '/if/LightSensor/0';             // specify the datapoint's request channel 
    let payload = '{ "nvoLuxLevel": { "monitor": { "rate": 5 } } }';                                                 // specify the monitor rate
    mqttClient.publish (topic, payload);                                                                                       // publish the updates

                                                                                                                                                                                                                                                                   

IAP/MQ Datapoint Assignment

An assignment to Datapoint.value affects the value at the priority currently selected with prionull assignment relinquishes the value at the priority currently selected with prio. value can never be omitted, but it can be null.

The request channel Datapoint.value indicates the requested value. The feedback channel Datapoint value indicates the actual value, subject to prioritized values and overrides.   You will need to connect to the message broker first, then publish to the topic in question. The topic can be a reference to a block, a datapoint, the data point value property or a structure or field within the value property.  The topic plus the payload key(s) must clearly define the item in question.

You can assign datapoint values using the following topic (topics and blocks are described in Interface Blocks and IAP/MQ Topic Syntax):  

glp/0/{SID}/rq/dev/{Edge_Protocol_ID}/{Handle}/if/{Block_Type/{Block_Handle}                                                                                                                           

Examples

The following examples show four sample topics along with payloads.  The last example is a sample Node.js publish.

Topic:  glp/0/{SID}/rq/dev/lon/NodeA/if/LightCntrl/0/nviLampValue/value
      Payload: {"value": 100, "state": 1}


Topic
 glp/0/{SID}/rq/dev/lon/NodeB/if/SpaceComfortContoller/0/nviTempValue/value
      Payload: {22}     


Topic:  glp/0/T6tWycd/rq/dev/lon/d.1/if/DisplayCtl/0/
      Payload: {"nviLine1msg": {"value": {"ascii": "testing"}}}


Topic glp/0/T6tWycd/rq/dev/lon/d.1/if/DisplayCtl/0/nviLine1msg/value/ascii
      Payload: {"Hello World"}

Publish update in Node.js:

     let topic = 'glp/0/' + SID + '/rq/dev/lon/' + MyDeviceHandle  + '/if/TempController/0';
     let payload = '{ "SP": { "value": 20 }}';
     mqttClient.publish (topic, payload);
                                                                                                                                                                                                                                                                                            


IAP/MQ Sample App to Read and Display the Value of a Light Sensor

This sample app shows how to create a simple MQTT client app that reads the value of an NcMultiSensorExample light sensor.  There is no web page being served, this app simply gets the NV updates and shows them on the console.

Note: If this is not invoked on the SmartServer IoT itself, then port 1883 must be opened on your SmartServer IoT.

Connect

const mqtt = require('mqtt');
let sid = '';
let myDeviceHandle = 'myAppDev.1';                                                      // please replace with handle of your device
let mySmartServerIoT = 'mqtt://10.1.128.245:1883';                              // please replace with IP of your SmartServer IoT device

let mqttClient = mqtt.connect(szMySmartServerIoT);
mqttClient.on('connect', () => {
    mqttClient.subscribe('glp/0/././sid');
    }
)

Listen

// This example only receives two topics; either an SID or a LightSensor value

mqttClient.on('message', (topic, payload) => {
     let js = JSON.parse(payload);
     if (topic === 'glp/0/././sid') {
          sid = js;
          mqttClient.unsubscribe('glp/0/././sid');                                      // optional, not required to unsubscribe from the SID
          DoSubscribe ();                                                                           // subscribe to NV updates
          DoPublish ();                                                                               // set the monitor.rate to non-zero in order to get NV updates to occur
     } else {
          console.log(js.nvoLuxLeve.value);
     }
}
)

Subscribe

// There is only one LightSensor function block on the NcMultiSensorExample, FBindex is 0

function DoSubscribe () {
     let subscribe = 'glp/0/' + sid  + '/fb/dev/lon/' + myDeviceHandle  + '/if/LightSensor/0';
     mqttClient.subscribe(subscribe);                                                  // listen for NV updates

}

Publish

function DoPublish () {
     let topic = 'glp/0/' + sid + '/rq/dev/lon/' + myDeviceHandle  + '/if/LightSensor/0';
     let payload = '{ "nvoLuxLevel": { "monitor": { "rate": 5 } } }';
     mqttClient.publish(topic, payload);

}                                                                                                                                                                                                                                                            


IAP/REST Datapoint Value Operations

For each datapoint API, you can specify item reference fields (device_handleblock_nameblock_indexdatapoint_name, and datapoint_property) and queries. 

See Queries and Parameters for information on the reference fields and specifying queries as part of your request. 

Datapoint Value Reporting

Gets the current value for the datapoints specified using path parameters. (See Datapoint Value in the API Reference for more information.)

GET     /iap/devs/{device_handle}/if/{block_name}/{block_index}/{datapoint_name}/values                                                                                                         

Example of Retrieving Datapoint Values

Get Datapoint Values
REQUEST:
  GET   /iap/devs/17q2d9x.5/if/block/1/Volts_1/values 


RESPONSE:
[
    {
        "deviceId":"17q2d9x.5",
        "blockName":"block",
        "blockIndex":"1",
        "datapointName":"Volts_1",
        "deviceState":"provisioned",
        "deviceHealth":"normal",
        "values":{
            "level":17,
            "levels":{
                "17":-500
            }
        }
    }
]

Example of Retrieving a Page of Datapoints with Names that Match a Regular Expression

Get a Page of Datapoints
This example retrieves the first page of datapoints with name that match the ^nviDO regular expression, and with a page size of 25.
Note: noxs=true stops the CMS from creating a snapshot even though pagination is specified.


REQUEST:
  GET   /iap/devs/*/if/*/*/*+name=+^nviDO/*?pg=1&sz=25&noxs=true 


RESPONSE:
[
  {
    "deviceId": "17q3cve.613",
    "blockName": "device",
    "blockIndex": "0",
    "datapointName": "nviDO3",
    "deviceState": "provisioned",
    "deviceHealth": "normal",
    "interfaceType": "static",
    "default": null,
    "values": {
      "level": 17,
      "levels": {
        "17": 0
      },
      "inactive": {}
    },
    "cat": "in",
    "property": false,
    "monitor": {
      "cat": "data",
      "rate": 0,
      "focus": null,
      "report": "change",
      "lon.cfg": {
        "maxRcvTime": 0,
        "propagationThrottle": 0,
        "propagationHeartbeat": 0,
        "propagationThreshold": 0
      },
      "throttle": 0,
      "heartbeat": 0,
      "threshold": 0,
      "inFeedback": false
    },
    "type": "SNVT_count",
    "value": 0,
    "lon.cfg": {
      "tag": {},
      "unit": "units",
      "label": "nviDO3",
      "handle": 2,
      "length": 2,
      "address": 16381,
      "forward": {},
      "persistent": false
    },
    "desc": ""
  },
  {
    "deviceId": "17q3cve.613",
    "blockName": "device",
    "blockIndex": "0",
    "datapointName": "nviDO2",
    "deviceState": "provisioned",
    "deviceHealth": "normal",
    "interfaceType": "static",
    "default": null,
    "values": {
      "level": 17,
      "levels": {
        "17": 0
      },
      "inactive": {}
    },
    "cat": "in",
    "property": false,
    "monitor": {
      "cat": "data",
      "rate": 0,
      "focus": null,
      "report": "change",
      "lon.cfg": {
        "maxRcvTime": 0,
        "propagationThrottle": 0,
        "propagationHeartbeat": 0,
        "propagationThreshold": 0
      },
      "throttle": 0,
      "heartbeat": 0,
      "threshold": 0,
      "inFeedback": false
    },
    "type": "SNVT_count",
    "value": 0,
    "lon.cfg": {
      "tag": {},
      "unit": "units",
      "label": "nviDO2",
      "handle": 1,
      "length": 2,
      "address": 16382,
      "forward": {},
      "persistent": false
    },
    "desc": ""
  },
  {
    "deviceId": "17q3cve.613",
    "blockName": "device",
    "blockIndex": "0",
    "datapointName": "nviDO1",
    "deviceState": "provisioned",
    "deviceHealth": "normal",
    "interfaceType": "static",
    "default": null,
    "values": {
      "level": 17,
      "levels": {
        "17": 0
      },
      "inactive": {}
    },
    "cat": "in",
    "property": false,
    "monitor": {
      "cat": "data",
      "rate": 0,
      "focus": null,
      "report": "change",
      "lon.cfg": {
        "maxRcvTime": 0,
        "propagationThrottle": 0,
        "propagationHeartbeat": 0,
        "propagationThreshold": 0
      },
      "throttle": 0,
      "heartbeat": 0,
      "threshold": 0,
      "inFeedback": false
    },
    "type": "SNVT_count",
    "value": 0,
    "lon.cfg": {
      "tag": {},
      "unit": "units",
      "label": "nviDO1",
      "handle": 0,
      "length": 2,
      "address": 16383,
      "forward": {},
      "persistent": false
    },
    "desc": ""
  },
  {
    "deviceId": "17q3cve.613",
    "blockName": "device",
    "blockIndex": "0",
    "datapointName": "nviDO_Mode",
    "deviceState": "provisioned",
    "deviceHealth": "normal",
    "interfaceType": "static",
    "default": null,
    "values": {
      "level": 17,
      "levels": {
        "17": {
          "char_set": 0,
          "wide_char": ""
        }
      },
      "inactive": {}
    },
    "cat": "in",
    "property": false,
    "monitor": {
      "cat": "data",
      "rate": 0,
      "focus": null,
      "report": "change",
      "lon.cfg": {
        "maxRcvTime": 0,
        "propagationThrottle": 0,
        "propagationHeartbeat": 0,
        "propagationThreshold": 0
      },
      "throttle": 0,
      "heartbeat": 0,
      "threshold": 0,
      "inFeedback": false
    },
    "type": "SNVT_str_int",
    "value": {
      "char_set": 0,
      "wide_char": ""
    },
    "lon.cfg": {
      "tag": {},
      "unit": "Wide character string.",
      "label": "nviDO_Mode",
      "handle": 17,
      "length": 31,
      "address": 16366,
      "forward": {},
      "persistent": false
    },
    "desc": ""
  }
]

Example of Retrieving a Page of Historical Datapoints with Names that Match a Regular Expression

Get a Page of Historical Datapoints
This example retrieves the first page of historical datapoints with names that match the ^nvo regular expression, and with a page size of 25.


REQUEST:
  GET   /iap/devs/*/if/*/*/*+name=+^nviDO/logs/value/*?pg=1&sz=25 


RESPONSE:
[
  {
    "id": 416085,
    "local": "2019-04-02 06:37:23.198 UTC",
    "utc": "2019-04-02 06:37:23.198 UTC",
    "deviceId": "17q3cve.613",
    "blockName": "device",
    "blockIndex": "0",
    "datapointName": "nvoEPpos",
    "deviceState": "provisioned",
    "deviceHealth": "normal",
    "value": 0,
    "tags": [
      {
        "log_level_1": "1"
      },
      {
        "log_level_2": "2"
      },
      {
        "log_level_3": "3"
      }
    ]
  },
  {
    "id": 426885,
    "local": "2019-04-01 23:43:19.581 PDT",
    "utc": "2019-04-02 06:43:19.581 UTC",
    "deviceId": "17q3cve.613",
    "blockName": "device",
    "blockIndex": "0",
    "datapointName": "nvoEPpos",
    "deviceState": "provisioned",
    "deviceHealth": "down",
    "value": 0,
    "tags": [
      {
        "log_level_1": "1"
      }
    ]
  },
  {
    "id": 557163,
    "local": "2019-04-02 09:24:55.764 UTC",
    "utc": "2019-04-02 09:24:55.764 UTC",
    "deviceId": "17q3cve.613",
    "blockName": "device",
    "blockIndex": "0",
    "datapointName": "nvoEPpos",
    "deviceState": "provisioned",
    "deviceHealth": "normal",
    "value": 0,
    "tags": [
      {
        "log_level_1": "1"
      },
      {
        "log_level_3": "3"
      },
      {
        "log_level_2": "2"
      }
    ]
  },
  {
    "id": 557172,
    "local": "2019-04-02 09:24:55.764 UTC",
    "utc": "2019-04-02 09:24:55.764 UTC",
    "deviceId": "17q3cve.613",
    "blockName": "device",
    "blockIndex": "0",
    "datapointName": "nvoPF",
    "deviceState": "provisioned",
    "deviceHealth": "normal",
    "value": {
      "point": [0, 0, 0, 0, 0, 0, 0],
      "interp_pts_0_to_1": 0,
      "interp_pts_1_to_2": 0,
      "interp_pts_2_to_3": 0,
      "interp_pts_3_to_4": 0,
      "interp_pts_4_to_5": 0,
      "interp_pts_5_to_6": 0,
      "interp_pts_6_to_0": 0
    },
    "tags": [
      {
        "log_level_1": "1"
      },
      {
        "log_level_2": "2"
      },
      {
        "log_level_3": "3"
      }
    ]
  },
  {
    "id": 562736,
    "local": "2019-04-02 02:28:48.323 PDT",
    "utc": "2019-04-02 09:28:48.323 UTC",
    "deviceId": "17q3cve.613",
    "blockName": "device",
    "blockIndex": "0",
    "datapointName": "nvoPF",
    "deviceState": "provisioned",
    "deviceHealth": "normal",
    "value": {
      "point": [0, 0, 0, 0, 0, 0, 0],
      "interp_pts_0_to_1": 0,
      "interp_pts_1_to_2": 0,
      "interp_pts_2_to_3": 0,
      "interp_pts_3_to_4": 0,
      "interp_pts_4_to_5": 0,
      "interp_pts_5_to_6": 0,
      "interp_pts_6_to_0": 0
    },
    "tags": [
      {
        "log_level_1": "1"
      }
    ]
  }
]


Datapoint Value Assignment

Gets the current value for the datapoints specified using path parameters. (See Datapoint Value in the API Reference for more information.)

Put    /iap/devs/{device_handle}/if/{block_name}/{block_index}/{datapoint_name}/values

Example

Datapoint Value Assignment
REQUEST:
  PUT    /iap/devs/17q2d9x.5/if/block/1/Volts_1/values


PAYLOAD: 
{"level":19,"levels":{"17":-500}}


Success


IAP/WS Datapoint updates

IAP/WS is only used to get datapoint value updates and is not used to write to these datapoints. Use IAP/REST to write to the datapoints.

To use IAP/WS, first create a general purpose WebSocket followed by an IAP/REST subscribe request with a list of datapoint that you wish to see updates. Datapoint WebSocket updates will show up due to On-demand GET request (IAP/REST), polling or anything other application causing events for these datapoints. To see a different set of datapoints issue another IAP/REST subscribe request.

The general purpose WebSocket will show more than just datapoint value updates. It will also show device status, alarms any other updates that the CMS may use. Each datapoint update is for a single object like a single datapoint value, single device status or single alarm.

See the IAP/REST Queries and Parameters for information on the reference fields and specifying subscribe and On-demand queries as part of your request. 

WebSocket Datapoint Value Updates Based on IAP/REST Subscribe datapoint List

IAP/REST command used to specify which datapoints show up in the WebSocket.

PUT   


/iap/dp/updates/subscribe    
 Payload: 
[{dpQualifierList}]                                                                                         

Note: If you have two WebSocket Web pages (CMS or custom) open by the same user the last Web page that sent the request subscribe request control which datapoints are shown in the WebSocket

Example of Retrieving Datapoint Values Using WebSockets

Get Datapoint Values
IAP/WS  CREATE WEBSOCKET CONNECTION:
	GET /iap/ws

IAP/REST SUBSCRIBE TO LIST OF DATAPOINTS:
	PUT /iap/dp/updates/subscribe
	Payload ["17qam77/lon/1/device/0/nvoLuxLevel","17qam77/lon/2/device/0/nvoLamp[1]"]

IAP/REST ON-DEMAND GET REQUEST:
GET /iap/devs/*/if/*/*/*+qualifier=-17qam77/lon/1/device/0/nvoLuxLevel,17qam77/lon/2/device/0/nvoLamp[1]/value?max_age=2&noxs=true


IAP/WS WEBSOCKET UPDATES: 
{"action":"UPD:DATAPOINT","payload":[{"datapointQualifier":"17qam77/lon/1/device/0/nvoLuxLevel","value":158,"locValue":158,"priorityArray":null,"blockName":"device","blockIndex":0,"datapointName":"nvoLuxLevel"}]}

{"action":"UPD:DATAPOINT","payload":[{"datapointQualifier":"17qam77/lon/1/device/0/nvoLamp[1]","value":{"value":0,"state":0},"locValue":{"value":0,"state":0},"priorityArray":null,"blockName":"device","blockIndex":0,"datapointName":"nvoLamp[1]"}]}