Skip to main content

Tridium Niagara N4 (oBIX)

GEM integrates with Tridium Niagara N4 / AX JACE controllers — and any oBIX-compliant building automation server (Honeywell Vykon, Distech ECx, JCI FX, Lynxspring Onyxx) — through the OASIS oBIX REST contract. Each Niagara station point is exposed as a GEM zone, with bool/level reads and writes flowing through /obix/... endpoints over HTTP(S).

This is the right driver to use when an integrator wants to drag in a BACnet-rich Tridium graphic into a GEM dashboard, expose JACE schedule writes to GEM macros, or surface fan/setpoint overrides on a wall touchscreen.

Prerequisites

  • Niagara station running N4.x (AX legacy works but is untested here) with the obix module loaded.
  • An ObixServerExt (or the older ObixNetwork server) under Station → Services, with HTTP Basic authentication enabled. The default oBIX URL is http://<jace>/obix.
  • A station user account with operator-level read + invoke permission on the points you plan to control. Do not use the station admin account.
  • Network reachability from the GEM controller to the JACE on the station HTTP port (typically 80 or 443).

If the site fronts Niagara with a reverse proxy or the station uses Niagara Cookie Digest auth, you must either enable Basic auth on ObixServerExt or place GEM behind the proxy on the same auth context — this driver only sends HTTP Basic.

Setup

  1. Add a device with driver niagara_obix.
  2. Set ip to the JACE IP/hostname. Set port to the station HTTP port (default 80) and protocol to http or https.
  3. Set username and password to the station operator account.
  4. (Optional) Set obix_root if the site has remapped oBIX away from /obix.
  5. Save and connect. The connect path issues GET /obix/ to confirm credentials.
  6. Run get_lobby from the script console to see the top-level oBIX containers exposed by the station.
  7. Walk into the station tree with get_children calls (each child has an href pointing at the next level).
  8. For each controllable point, create a zone whose address is the oBIX href (absolute /obix/config/Drivers/... or station-relative config/Drivers/...).

Attribute Reference

Device

NameTypeRequiredDefaultNotes
ipstringyesJACE IP/hostname.
usernamestringyesStation operator account.
passwordstringyesEncrypted at rest.
portintno80Station HTTP/HTTPS port.
protocolstringnohttphttp or https. Self-signed certs are accepted.
obix_rootstringno/obixRoot path where the oBIX server is mounted.
status_intervalintno30000Per-zone polling cadence (ms).

Zone

NameTypeRequiredDefaultNotes
addressstringyesoBIX href for the point.
point_typestringnoboolbool, int, real, or str. Controls how on/off/set_level encode the body.

Zone Address Format

zone.address is the oBIX href of the underlying point. Both shapes are accepted:

  • Absolute: /obix/config/Drivers/BacnetNetwork/AHU1/SupplyFan
  • Station-relative: config/Drivers/BacnetNetwork/AHU1/SupplyFan

The driver normalizes the path against obix_root before each request, so either form works.

Commands

CommandArgsDescription
onaddressSet the point to true (bool) or 1 (int/real).
offaddressSet the point to false / 0.
set_leveladdress, levelWrite a numeric value using the zone's point_type (defaults to real).
get_pointaddressRead a point and return {value, raw}. raw is the original XML.
set_pointaddress, value, contractWrite any contract type (bool, int, real, str).
invokeaddress, bodyPOST a raw oBIX XML body to an invoke href — escape hatch for BACnet override and station-specific ops.
get_lobbyList children of the oBIX root.
get_childrenaddressList children of an oBIX path for discovery.

Known Limitations

  • The driver uses a small regex parser for val= attributes rather than a full XML parser. Complex objects (lists with mixed children, history queries) come back as raw XML through get_point; the caller is responsible for parsing them.
  • POST /set enforces oBIX contract matching — writing a <real> body to a <bool> point fails with a contractMismatch error. Align the zone's point_type with the underlying point.
  • BACnet override semantics are not auto-generated. The typical override body is <obj><real name="value" val="..."/><reltime name="duration" val="PT1H"/></obj> against the point's invoke href; drop that XML into the invoke command for now.
  • WebSocket / Watch contracts are not implemented. State is reflected via periodic polling.

Troubleshooting

  • 401 Unauthorized — the user does not have oBIX permission, or ObixServerExt is not set to Basic. Verify in Workbench under Services → ObixServerExt → Authentication Scheme.
  • 404 on /obix/ — the obix module is not loaded, or the station has remapped the root path. Try setting obix_root to the configured path.
  • contractMismatch errors — the body type doesn't match the point. Use get_point first to discover the existing contract.
  • Timeouts on every request — confirm the station HTTP port is reachable (curl -u user:pass http://<jace>/obix/ from the GEM host).