#34 Proposed Niagara Haystack implementation and method for querying Haystack models in Niagara

Richard McElhinney Thu 29 Sep 2011

So far there has been no open standard way to apply Project Haystack modelling to Niagara AX databases. This post outlines a proposed design for applying Haystack tags on Niagara AX systems as well as a method to query a Niagara AX system for the tag model and data.

While this proposal is targeted at Niagara AX systems, the aim is to produce as best as possible a generic design that allows a similar implementation by other BMS platforms.

The outcome of this design would be to produce an open source Niagara AX module as an example implementation of this proposal.

It draws on the work of Brian Frank in his creation of the Haystack Java Toolkit and also some of the discussions Brian has had with other interested people.

Basic Requirements

  1. Easy way from within Niagara to add tags to points
  2. Easy way from within Niagara to annotate a point's site/equip
  3. Store the tags so they can be searched
  4. Maybe simple index of the tags for quick tag based queries
  5. Easy way to query point list from Niagara with proper tags
  6. Easy way to sync histories from Niagara using CSV
  7. Allow single push button import of tag models and data out of Niagara AX stations into other analysis tools

Proposed Design

The design of this system has 2 parts.

The first being the proposed implementation of the Haystack tag model that allows the application of tags to Niagara AX points/folders.

The second part is the design of a servlet REST API that is implemented in this case as a Niagara AX Web Servlet. However the REST API should be generic enough to be implemented by other systems and return the same data for all queries.

All tag models and history data are represented and encoded as CSV records.

1. Haystack Tag Model Implementation

The implementation of Haystack tags would centre around creating a Niagara component for each tag. Each tag type would subclass BComponent. This allows simple addition of tags to a Niagara point/folder from a palette.

All tags should be contained within a point/folder extension. This extension would be called BTagMapExt.

Why BTagMapExt?

The point model in Niagara encourages the use of extensions to enhance the standard behaviour of a control point. A Tag Map Extension makes searching a Niagara database for tags easier. For example, when building a point list with tags, a BQL query need only look for all the TagMapExt's in database and then iterate through the result set to check for the points which have the point tag.

A TagMapExt also give a concrete place holder to navigate the Niagara database tree structure. Furthermore BTagMapExt will contain an up to date CSV string encoding of the tags/vals that have been configured. This will speed up the creation of a servlet response by allowing this CSV record to be used rather than reconstructing the record each time a query is run.

The following subclasses of BComponent are proposed to encapsulate the different Haystack tag types:

BBoolTag
BDateTag
BDateTimeTag
BMarkerTag
BNumTag
BRefTag
BStrTag
BTimeTag
BUriTag

The following is an example folder/point structure for an AHU.

AHU                          // Niagara AX point or folder component
|
|-TagMapExt                  // BTagMapExt component 
|   |
|   |-axUuid                 // BRef component
|   |-equip                  // BMarker component
|   |-ahu                    // BMarker component
|   |-hvac                   // BMarker component
|   |-axRef                  // BRef component
|
|-dischargeAirTemp           // Niagara AX control point component
    |
    |-TagMapExt              // BTagMapExt
        |
        |-axUuid             // BRef component
        |-point              // BMarker component
        |-discharge          // BMarker component
        |-air                // BMarker component
        |-temp               // BMarker component
        |-in                 // BMarker component
        |-axRef

The corresponding CSV for the AHU and the associated point would be:

dis,ahu,axRef,axUuid,equip,hvac
AHU,✓,h11,h2a,✓,✓

dis,axRef,axUuid,air,discharge,in,point,temp
dischargeAirTemp,h33,h2a,✓,✓,✓,✓,✓

The axUuid tag has been introduced to provide a Niagara specific unique identifier that can be referenced using the axRef tag. This removes any requirements for hard tree structures/hierarchies to be implemented in Niagara databases. It also allows for external tools reading this data out of Niagara to place their own interpretation on the use of these tags and how referencing between specific records is accomplished.

For example if Skyspark was reading the above equip CSV record, and assuming a site record had already been created with the axUuid:h11, it would use the axRef tag to look up the site record and then add in the siteRef tag with the corresponding RecId.

Likewise, the above point record would use its axRef value to look up the AHU which had been added and then create the equipRef tag with the appropriate RecId.

The axUuid and axRef tags are string representations of a Niagara Handle ORD.

Niagara AX Tagging Rules

For clarity, a generic set of tagging rules should be developed that can be implemented to ensure consistency of tag models. For example:

If a point/folder has the 'ahu' tag it must also have the 'equip' and 'hvac' tags.  

These rules should be defined as part of the Project Haystack documentation and may already exist, but just need some clarification or formalisation. The following points outline some Niagara specific rules that should be adopted as part of this proposed design and incorporated into any implementation.

  1. New tags axUuid and axRef tags are string representations of a Niagara Handle ORD.
  2. For Niagara points/folders that have the equip tag, the axRef tag must be added. This will reference a corresponding Niagara point/folder that has the site tag.
  3. For Niagara points that have the point tag, the axRef tag must be added. This will reference a corresponding Niagara point/folder that has the equip tag.

Problems

No design is perfect!! :) So there are a couple of specific issues that the community may wish to comment on.

One outstanding issue exists that may or may not be specific to Niagar AX databases. Depending on how a BMS is engineered it may have a Niagara Supervisor managing a number of Niagara JACE controllers. Commonly the points are engineered in the JACE, as is the history collection for corresponding time series data. This time series data is then archived to the Niagara Supervisor.

So the question is, where is the Haystack model defined in this architecture. Is it in multiple JACE controllers, therefore ensuring that to read a Haystack model may require the querying of multiple JACE's. Or is it defined in the Niagara Supervisor changing how the Supervisor - JACE relationship is defined.

This proposal makes the assumption that the Haystack model is defined in the Niagara Supervisor, or for sites that use a JACE as the main site supervisor the Haystack model is defined in the JACE.

Secondly, the introduction of axUuid and axRef tags, and the idea behind their use, may create more processing and work for an external tool reading the Haystack model. Some solution is required for this though as the ability to annotate the site/equip/point relationship in Niagara is a requirement.

2. Servlet REST API

The following outlines the proposed REST API. Each section defines the standard URI's, examples of the URI's where needed that examples of the data that is returned in the servlet response.

All data in the servlet response is to be encoded as CSV according to RFC 4180. Character encoding is set to UTF-8.

Base

Return servlet version and other information as required.

GET       /haystack                                           

// CSV
ver,ts
1.0,"2011-09-29T12:00:00+10:00"

History Queries

Return number of values,type of history, units.

GET       /haystack/api?his={history_id}

//CSV
count,type,unit
1500,Num,kW

Query history for values for today, same for following queries just different ranges.

GET       /haystack/api?his={history_id}&range=today          
GET       /haystack/api?his={history_id}&range=yesterday
GET       /haystack/api?his={history_id}&range=weekToDate
GET       /haystack/api?his={history_id}&range=lastWeek
GET       /haystack/api?his={history_id}&range=monthToDate
GET       /haystack/api?his={history_id}&range=lastMonth
GET       /haystack/api?his={history_id}&range=yearToDate
GET       /haystack/api?his={history_id}&range=lastYear
GET       /haystack/api?his={history_id}&range={yyyy-mm}

// CSV
ts,val
"2011-09-29T12:00:00+10:00",10.0
"2011-09-29T12:15:00+10:00",21.0
"2011-09-29T12:30:00+10:00",14.0
"2011-09-29T12:45:00+10:00",17.0

Site Query

Query the site information out of a running Niagara AX station.

GET       /haystack/api?site                                  

// CSV
dis,site,geoAddr,area,tz,weatherRef
HQ,✓,"1600 Pennsylvania Avenue NW, Washington, DC",55000ft²,New York

Point Query

Query Niagara station to build and return a map of all control points that have the point tag.

GET       /haystack/api?point

// CSV
axUuid,dis,point,axRef
h2a,dischargeTemp,point,h3c

Equip Query

Query Niagara station to build and return a map of all control points that have the point tag.

GET       /haystack/api?equip

// CSV
axUuid,dis,equip,axRef
h2a,RTU1,✓,h1e

Tag Query

Query a Niagara station for a list of points that meet the criteria defined by filter.

GET       /haystack/api?tag={filter}                          

Examples:
GET       /haystack/api?tag=ahu
GET       /haystack/api?tag=chiller
GET       /haystack/api?tag=ahu%20and%20rooftop
GET       /haystack/api?tag=equip

Next Steps

We are looking for comment on this proposal from the Haystack community. Initial work has already been started on sketching out some of the source code for the tag implementation. This will be published shortly for further review and to accompany this proposal.

All feedback, suggestions and comments are welcome.

I would like to start work on the implementation of this proposal as soon as possible, as I have a need for it in my own work.

Brian Frank Fri 30 Sep 2011

Richard, thanks for kicking off this discussion. There are quite a few people who are in both the Niagara and Haystack communities who are interested in this. Here are some of my thoughts:

Human Problem

The fundamental problem with modeling is getting the installer to do it in the first place. So it needs to be easy as possible to have a hope that it gets done. And if you put in the effort, it would be nice if it provides immediate benefits like auto-generation of displays/graphics/navigation or something. For canned apps like a VAV control app duplicated 100 times, it is probably easier to justify putting the modeling work up front. Also we have to remember that we have a huge installed base without decent modeling or even naming conventions. So I think the human side is important to consider, even if we can just move the dial a bit and get consistent naming conventions that are easy to regex into a model database.

Niagara Issues

As far as how tags might be stored in Niagara, here are some issues to consider:

  • store as a BComponent under each point (your idea)
  • store as tags as encoded BSimple (my orig thoughts when I posted toolkit)
  • store as an overlay over component/history tree as map from naming conventions

Each has its pros and cons:

  • your idea to create a PointExt might be awkward for non-points you could model in Niagara like sites or equip
  • components easier to work with via existing tools
  • simples way more efficient and can be associated with component directly
  • overlay is probably most effective for a system already built

I am not sure which of these option or options makes sense. But I think the one big issue is that from an analytics perspective the BHistory is the real "point". If you do things in the component tree, then that might complicate life. For example are you going to require a BComponent in the Supervisor for every point that might be imported from a Jace?

Also don't think you need to create new BxxxTag types, since the Niagara types already map pretty much directly to oBIX/Haystack/SkySpark types.

As far as identifiers, I would just keep it simple. The id tag is the unique identifier string whatever it is (handle, slot ord, UUID, etc). And reference tags use the Java toolkit encoding equipRef=<abcd> "Chiller-1". One thing that we proved out in SkySpark is that encoding a reference as an identifier/dis tuple is extremely useful to avoid extra network lookups.

Rest API

John kicked off an interesting discussion about oBIX and XML representation of Haystack tags. Even though I was deeply involved in oBIX, I've begun to think it is overkill for what is needed for simple modeling and how data import processes work. I prefer simple tabular data in CSV which is much easier to work with in import scripts, pass around and edit with Excel, etc. So I like the idea of making CSV at least one of the formats to query model/history data.

To me, a simple REST API with two command is all that is needed:

GET /haystack/query?{query}
GET /haystack/his/{id}?{range}

We could start off with query being as simple as just a tag name - that would give me quick, easy way to query sites, equips, points, etc. Plus I think we can use simple and/or/compare query language that I would be happy to code up in a reusable way in the Java toolkit.

Reading history data as simple CSV of timestamp/value pair is something sorely lacking in Niagara today, so that would be super nice too. We can hash out simple way to express different ranges, but your 90% case is to sync up with all data after a specific timestamp. Plus sometimes its nice to handle date, date range, etc for the histories specific timezone. This I am also happy to code up in a resuable way in the Java toolkit.

Joel Bender Fri 30 Sep 2011

The fundamental problem with modeling is getting the installer to do it in the first place. So it needs to be easy as possible to have a hope that it gets done.

Speaking from experience, the only way to get it done is to pay to have it done, which means getting into the specification so the vendor recognizes that it is something for which they are going to be held accountable, and then make sure it was actually done during commissioning and acceptance. Otherwise, this is just something nice to have.

Richard McElhinney Sun 2 Oct 2011

@Brian and @Joel, thanks for the responses and thoughts.

Perhaps to summarise a little so we don't get lost; there seems to be three areas that need to be addressed.

  1. Human Factor
  2. REST API
  3. Creating models in Niagara

Human Factor

In my view the goal of this is to try and produce a tool or solution that fosters and enables the construction of good models in Niagara and sets an example for other BMS platforms. Whether the models are used for a Skyspark interface or graphic auto-generation shouldn't matter.

So for me, and I realise I'm not the only one here :), the process of convincing clients/consultants/contractors that it should be done is a side issue and one that we can all work on through promoting Project Haystack and the benefits it brings. If we achieve the goal of a nice easy tool to use in Niagara then it should make the job of convincing people to use it a bit easier.

REST API

I'm all for keeping it as simple as possible so I quite like Brian's suggestions.

@Brian, anything you can add to the Haystack Java toolkit to help out would be greatly appreciated.

I'm happy to start putting some of the plumbing together to get a basic servlet up and running to do some history queries based on your suggestions.

Creating models in Niagara

This seems to be the biggest problem to solve at the minute. I agree with Brian that from an analytics point of view most of the data we are interested in resides in histories, and that duplicating models as a component tree or forcing points to be imported into a supervisor to create a model is difficult to justify.

So does that mean we should be placing tags on our Niagara histories?

Annotating the site/equip details of a site in Niagara is a bit more difficult. So I guess a little creative thinking is required.

Would be good to hear from others in the Niagara/Haystack community as to how they would like to use a tool so they can create Haystack model in Niagara?

Brian Frank Mon 3 Oct 2011

I will push some new code for Java Haystack Toolkit (hopefully tomorrow) with some new features like query handling.

Mike Silady Wed 4 Apr 2012

Good Work!

I've got the hayStack module in my Niagara Station. I've built-out the haystack/Project/Site/Equip references. I've tagged a few points with the His Tag function. >>Richard,

What is the File field used for in the Haystack Service's properties?
How do you proceed from here when you start a new job?
In "His Tag", how do you page down past the AHU tags?
Do you add your equipRefs to the histories on the skySpark side?
Are there tricks that I'm missing?

I've got the haystack Conn made in skySpark. In folio: haystackReadQuery(read(haystackConn), "site") returns the site. In folio: haystackReadQuery(read(haystackConn), "temp") returns the "first history tagged". Yeah!!!! >>Brian and Richard,

What's are the next steps?

I'd like to leave a better path for others to follow.

Thanks again. Mike

Login or Signup to reply.