Niagara Central HomeKnowledge BaseBlogsForumsCreate Account | Login
Gareth Johnson

A Beginner's Guide to oBIX (even if you're not a developer!) - Part 5

Posted by Gareth Johnson | 04-Dec-07 11:41 AM EST

This week I'm going to talk about accessing histories using oBIX. Accessing histories is quite a straight forward process in oBIX as I'm sure you'll see.

For the purposes of this demonstration, I've created a history in Niagara so it can be exposed through oBIX.

To begin with, let's open a Web Browser and log into the oBIX lobby. There you'll see a reference to the histories. If you click on that, you'll get a list of history devices. Each history device can contain many history objects. After clicking on a history device, you'll see a list of the actual histories we'll be working with...

<obj href="http://localhost/obix/histories/test/" display="javax.baja.history.BHistoryDevice">
  <ref name="NumericWritable" href="NumericWritable/" is="obix:History" />
</obj>

You'll notice that each history implements the generic 'obix:History' Contract. This object represents a normalized version of a history. Click on the history and you should see something like...

<obj href="http://localhost/obix/histories/test/NumericWritable/" is="obix:History" >
  <int name="count" val="500"/>
  <abstime name="start" val="2007-06-25T09:51:15.062+01:00"/>
  <abstime name="end" val="2007-11-19T09:01:14.062Z"/>
  <op name="query" href="~historyQuery/" in="/obix/def/obix:HistoryFilter" out="/obix/def/obix:HistoryQueryOut"/>
  <op name="rollup" href="~historyRollup/" in="/obix/def/obix:HistoryRollupIn" out="/obix/def/obix:HistoryRollupOut"/>
  <feed name="feed" href="~historyFeed/" of="/obix/def/obix:HistoryRecord" in="/obix/def/obix:HistoryFilter"/>
  <ref name="today" href="~historyQuery?start=2007-11-19T00:00:00.000Z"/>
  <ref name="last24Hours" href="~historyQuery?start=2007-11-18T09:01:14.687Z"/>
  <ref name="yesterday" href="~historyQuery?start=2007-11-18T00:00:00.000Z&amp;end=2007-11-18T23:59:59.999Z"/>
  <ref name="weekToDate" href="~historyQuery?start=2007-11-18T00:00:00.000Z"/>
  <ref name="lastWeek" href="~historyQuery?start=2007-11-11T23:59:59.999Z&amp;end=2007-11-17T23:59:59.999Z"/>
  <ref name="last7Days" href="~historyQuery?start=2007-11-12T09:01:14.687Z"/>
  <ref name="monthToDate" href="~historyQuery?start=2007-11-01T00:00:00.000Z"/>
  <ref name="lastMonth" href="~historyQuery?start=2007-10-01T00:00:00.000+01:00&amp;end=2007-10-31T23:59:59.999Z"/>
  <ref name="yearToDate (limit=1000)" href="~historyQuery?start=2007-01-01T00:00:00.000Z&amp;limit=1000"/>
  <ref name="lastYear (limit=1000)" href="~historyQuery?start=2006-01-01T00:00:00.000Z&amp;end=2006-12-31T23:59:59.999Z&amp;limit=1000"/>
</obj>

The object looks quite big doesn't it? We'll don't worry, some extra querying capabilities have been added to make developers lives easier.

The 'count' integer refers to the number of records stored by the history. The 'start' and 'end' date times (abstime) refer to newest and oldest records in the history.

Now 99% of the time, you'll just want to query the history to get some records back. This can be achieved in a two different ways...

  1. The references at the bottom of the history object ('today', 'last24Hours', 'yesterday' etc.), can be used to query the history and get back records. From the Web Browser, just try clicking on these links. You'll notice that a standard HTTP GET will get back the record data.
  2. Or use the '~historyQuery' Operation.

The query Operation takes an object that implements the 'obix:HistoryFilter' Contract...

<obj is="obix:HistoryFilter">
  <int name="limit" val="10">
  <abstime name="start" val="2007-06-25T09:51:15.062Z"/>
  <abstime name="end" val="2007-11-19T09:01:14.062Z"/>
<obj/>

Therefore, if you HTTP POST the above document to the query Operation URI, you'll get back a list of history records. You may be wondering at this point, 'Why should I use the query Operation when I can perform a simple HTTP GET?'. Using the query Operation is the standard oBIX Operation included in the Contract, so I advise you use this if you can. Please note, always follow the schema being specified especially for formatting the date times (refer to ISO 8601) - always remember to include seconds and the desired timezone.

Before, we dive into the history records, note the 'limit' integer that can be specified in the 'HistoryFilter'. This curbs the number of history records we get back in a single request. Therefore, if you're expecting the possibility of getting back a 'lot' history records, it would be prudent to set this to a limit (i.e. 100) and make multiple requests.

The HTTP GET method uses the same Properties (start, end and limit) except these are encoded as extra parameters in the URI. Also, the HTTP GET method is only applicable to a Niagara based oBIX Server and hence is not part of the generic oBIX standard.

Once a query has been made, the following document is given as the response...

<obj is="obix:HistoryQueryOut" >
  <list name="data" of="#RecordDef obix:HistoryRecord">
    <obj>
      <abstime name="timestamp" val="2007-11-19T09:31:12.953Z"/>
      <real name="value" val="22.217134475708008"/>
    </obj>
    <obj>
      <abstime name="timestamp" val="2007-11-19T09:31:13.984Z"/>
      <real name="value" val="31.62298583984375"/>
    </obj>
  </list>
  <int name="count" val="2"/>
  <abstime name="start" val="2007-11-19T09:31:12.953Z"/>
  <abstime name="end" val="2007-11-19T09:39:42.546Z"/>
  <obj href="#RecordDef" is="obix:HistoryRecord">
    <abstime name="timestamp"/>
    <real name="value" unit="obix:units/null"/>
  </obj>
</obj>

Parsing this information should be fairly straight forward. The list contains a number of history records with a time stamp and value. After the list, the number of records and the start and end time stamp are given. As with all oBIX development, you should always be mindful of the Contract being specified. In this particular case, the Contract for 'obix:HistoryRecord' is given at the bottom of the document.

History Rollup requests can also be made using the '~historyRollup' Operation. This works in a very similar way to the '~historyQuery' Operation. A History Rollup allows the user to access the count, min, max, average and sum of a history over a given time period. The '~historyRollup' Operation takes an object that implements the 'obix:HistoryRollupIn' Contract...

<obj is="obix:HistoryRollupIn">
  <reltime name="interval" val="PT1H" />  
</obj>

Please note, that a 'HistoryRollupIn' is also a 'HistoryFilter'. Therefore, 'limit', 'start' and 'end' can also be used. I can invoke the Operation via an HTTP POST to the '~historyRollup' URI (the interval being used here is 1 hour).

And the response...

<obj is="obix:HistoryQueryOut">
  <list name="data" of="obix:HistoryRollupRecord">
    <obj>
      <abstime name="start" val="2007-12-03T15:26:39.842Z"/>
      <abstime name="end" val="2007-12-03T15:35:11.311Z"/>
      <int name="count" val="499"/>
      <real name="min" val="2.807351411320269E-4"/>
      <real name="max" val="99.99894714355469"/>
      <real name="avg" val="50.000332826774155"/>
      <real name="sum" val="24950.166080560302"/>
    </obj>
  </list>
  <int name="count" val="1"/>
  <abstime name="start" val="2007-12-03T15:26:39.842Z"/>
  <abstime name="end" val="2007-12-03T15:35:11.311Z"/>
</obj>

The 'HistoryRollupRecord' contains all the information we're interested in and can be easily parsed. For more information, please read the official oBIX document available for download here.

Finally, we have the concept of being able to 'Watch' a history. A 'Watch' is covered in an earlier part of the guide. This enables us to subscribe to a real-time feed of history records. Each time the Watch is polled, we get back the latest set of history records. More information on a 'Watch' is available in an earlier part of the guide here.

Next time I'll be discussing the oBIX Batch Operation!


5 commentsLog in to add comment
Madhan Kumar wrote on 06-Dec-07 8:43 AM EST:

Hi Johnson,

I have been following your blog starting from Part 1. It is really good series of postings on Obix. Thanks.

While it is possible to follow the postings, it is a bit difficult to understand to an extent that we can make interpretations and try exposing some other object-parameters on our own.

It is difficult to understand how to get the "BEGIN BAJA AUTO GENERATED CODE" that you have in the source for any other program we try to do.

  1. BConnectionMethod.java
  2. BObixRequestTest.java
  3. HttpClient.java

Is there some Tridium guideline document for developers like " How to get started on exposing Niagara Objects?" that will help throw more light on the meaning/understanding behind the various files available in the source made available for download, the structure of folders and the XML files.

Saneesh Kumar wrote on 09-Dec-07 12:04 AM EST:

Gareth, A Beginner's Guide to oBIX - have been a good series. Wonderful job, thanks for well compiled session.

Gareth Johnson wrote on 10-Dec-07 6:02 AM EST:

Madhan, it sounds like you want to go on a developers course for Niagara AX to cover how to create and hence expose components. The developer course is run in both the USA and in the UK. If you're a software developer and want to go on the course please email supportuk 'at' tridium dot com.

Antony wrote on 15-Sep-08 6:48 AM EDT:

Hi Johnson, That was really great explanation and thank you so much for this.

And I have some very basic questions regarding the services and drivers in the sample online oBIX server your provided. Are these services and drivers listed in the online oBIX server standard or are just used for exampl purpose? and if so, where can I know the standard oBIX protocol? Can I get some skeleton of information of how the protocol looks like??

I am actually planning to develop a generic oBIX client. So, I need to know whether these services and drivers and the XML format are standard or they differ across servers so that I can program my client appropriately.

Your help will be much appreciated.

Tucker Watson wrote on 20-Aug-09 12:44 PM EDT:

Gareth -

I noticed you have a couple problems with your "HistoryFilter" xml format. The closing tag should be "" rather than "". Also you forgot to close the "limit" tag.

Log in to add comment