Learn AXON

To get points from bacnet connectors be sure you have already created bacnet connectors.

To get points from bacnet device it needs to use bacnetLearn function.


bacnetLearn(conn, uri)

Returns a grid with the BACnet objects residing on the device the connector points to. The way this works is that a call with only the connector record will return a grid of folders for each object type that connector supports.



The above will return a grid containing a dis and learncolumn, like:



Calling the function with a learn parameter will return a grid containing all objects of the learn parameter type, like:

bacnetLearn(@some-bacnet-conn-ref, `ANALOG_VALUE`)

This returns a grid like:


At first it needs to run it only with conn parameter to get uri parameter.

Example: read(bacnetConn).bacnetLearn


Then for each of uri in lear column needs to run read(bacnetConn).bacnetLearn(uri)

Example: read(bacnetConn).bacnetLearn(`ANALOG_INPUT`)


For each row from this table you should generate point record.

Besides usual point’s tags (navName, disMacro, cur, his, point, etc.) point should have special tags to get history from bacnet connector:

  • bacnetConnRef(ref) reference to bacnet connector
  • bacnetHis(Str) points to Trend_Log id 

Be sure trendLog tz is the same as point tz

If you want to get history with collecting curVal point should have next tags:

  • bacnetConnRef(ref) reference to bacnet connector
  • bacnetCur(Str) points to bacnet point object (example on the picture above)
  • hisCollectCov(marker) or hisCollectInterval(duration)

Axon function example

Also you can use a function to make all points from all connectors.

This function is designed to run as job. It is usefull when you want to handle many bacnet devices and create many points to avoid TimeoutError. Also you can see log in this case.

Also function has one parameter "importLimit". It is max number of point what will be created (usefull to avoid license error)

(importLimit: 5900) => do
 equips: readAll(equip)
 pointsToAdd: []
 site: read(site)
 numImported: 0
 devices: readAll(bacnetConn).toRecList
 devices.each(row => do
     logInfo("info","checking "+row["bacnetDevice"])
     objects: row.bacnetLearn().toRecList
     learn: null
     points: null
     if (objects.size > 0) do
       learn = objects.toGrid.colToList("learn").unique
     if (learn != null) do
       learn.each(type => do
         if (numImported >= importLimit) return null
         logInfo("info","checking "+row["bacnetDevice"]+" "+type.toStr)
         points = row.bacnetLearn(type).toRecList
         dev_pointsToAdd: checkPoints(points)
         if (not dev_pointsToAdd.isEmpty) do
           equip: readAll(equip).find(e => e["navName"]==row["bacnetDeviceName"])
           if (equip == null) do
           //create equip
              equipDiff: {}
              equipDiff = equipDiff.set("siteRef", site->id)
              equipDiff = equipDiff.set("tz", site->tz)
              equipDiff = equipDiff.set("navName", row["bacnetDeviceName"])
              equipDiff = equipDiff.set("tz", site->tz)
              equipDiff = equipDiff.set("siteRef", site->id)
              equipDiff = equipDiff.set("imported", marker())
              equipDiff = equipDiff.set("equip", marker())
              equipDiff = equipDiff.set("disMacro", "\$siteRef \$navName")
              equip = diff(null,equipDiff,{add}).commit
             dev_pointsToAdd = dev_pointsToAdd.toGrid
               .addCol("equipRef", row => equip["id"])
               .addCol("bacnetConnRef", r => row["id"])
               .addCol("siteRef", row => site["id"])
               .addCol("tz", row=> site["tz"])

             if (numImported + dev_pointsToAdd.size <= importLimit) do
               logInfo("info","Device: "+row["bacnetDevice"]+". Imported: " + dev_pointsToAdd.size + " points")
               numImported = numImported + dev_pointsToAdd.size
             end else do
               limit: importLimit - dev_pointsToAdd.size
               if (limit > 0) do
                 dev_pointsToAdd = dev_pointsToAdd[0..limit]
                 numImported = importLimit
       end) //end of learn.each

In function above we use checkPoint() function to generate point according to csv sheet where some specific tags was added to points. 

We find point in csv by dis and check if it has some specific additional tags and add it to standart set of tags ("navName", "point", "disMacro", etc.)

(points) => do
  pointsWithTags: `*link to csv file with points with tags*`.ioReadCsv
     .findAll(row => row["tags"]!=null or row["regex1"]!=null)
  regex: pointsWithTags.colToList("regex1")

  getChanges: (row) => do
   changes: {}
   row.each((value, tag) => do
     if (value!=null and tag!="dis") changes = changes.set(tag, value)
   return changes

  pointsToAdd: []
  points.each(point => do
   changes: {}
   dis: point["dis"]
//  example: reMatches(r"AHU-(\d+)", "AHU-10")
   regexMatch: null
   //regex.find(re=>reMatches(re, dis))
   navNameMatch: pointsWithTags.find(row => row["navName"]==dis)
   if (regexMatch != null or navNameMatch != null) do
     changes = getChanges(point)
     changes = changes.set("point",marker())
     changes = changes.set("navName",point["dis"])
     changes = changes.set("disMacro","\$equipRef \$navName")
     changes = changes.set("his",marker())
     changes = changes.set("cur",marker())
     changes = changes.set("collectBacnetHis",marker())
     changes = changes.set("hisCollectInterval", "15min")
     changes = changes.set("imported",marker())
     markers: null
     if (regexMatch != null) do
       markers: pointWithTags.find(row => row["regex1"]==regexMatch)
     end else do
       markers = navNameMatch["tags"]
     if (markers != null) do
       markersList: markers.split(" ")
       markersList.each(m => changes = changes.set(m,marker()))
     pointsToAdd = pointsToAdd.add(changes)
 return pointsToAdd

  • No labels