Niagara N4 Programming: Wiresheet, Program Objects, and When You Need a Module

Start with the smallest tool that holds the sequence

Work described as Niagara N4 programming can mean several different things. This article covers three of them: logic drawn on a wiresheet from stock components, a Program object holding Java that the station compiles, and a module you build outside the station and install on the platform. Other routes exist, including BQL queries and the legacy AX scripting that older stations still carry, and they are covered on their own pages.

These three are not rungs on a ladder you climb in order, and the risk is defaulting to whichever one you already know how to build. If a control sequence can be expressed in stock components and read off the sheet by whoever has to maintain it, the wiresheet is the answer. You go past it when the wiresheet and Program objects cannot express what the job needs, or when what you are building has to be versioned, tested and reused rather than drawn once on one station.

What the wiresheet actually does

The wiresheet is a view onto a component tree, not a drawing canvas. Every block is a component with slots, meaning properties, actions and topics, and every wire is a link between two slots. Blocks come from palettes: kitControl for math, logic, latches, timers and hysteresis, driver palettes for proxy points, and the alarm, history and schedule components around the control loop.

Execution is event driven rather than a scan cycle. When a linked slot changes, the target component executes and propagates downstream. That matters if you arrive from a PLC background: there is no sweep across the sheet, so feedback paths, one shot pulses and order dependent chains need explicit handling instead of an assumption that the sheet runs once per cycle.

The wiresheet is also the documentation: the next engineer sees the sequence itself, with live values on it, rather than a compiled artifact.

Signals that the wiresheet has stopped being the right container

None of these signals is about how clever the logic is, and none of them forces a module on its own. Repetition in particular is a structuring problem first, and the fix may be a folder structure or one reusable composite rather than code.

Reach for code when the shape of the problem, not its size, is wrong for blocks and links. These are the shapes that qualify:

  • The same pattern of blocks is repeated per zone, per room or per unit, and the copies keep multiplying.
  • The logic needs iteration or a data structure: walking a list of devices, ranking values, holding a rolling window.
  • Something has to be parsed or built, such as a CSV file, a JSON payload or a string returned by a device.
  • The station has to talk to a system no available driver covers, such as a vendor HTTP API or a service with its own authentication scheme.
  • You need an operator view that does not exist as a stock widget.

Program objects and what you trade for them

A Program object holds Java source that the station compiles, rather than code you build with an external tool chain. You add the slots you need, link them like any other component, and write the bodies that run on start, on execute and on stop. Whether that in station compilation is available depends on the Java tooling present on the platform you are targeting, so confirm it for the deployment in front of you rather than assuming it.

What you trade is lifecycle. The source lives in the station database, so it travels with a station backup rather than with your version control. There is no test harness, no dependency management, and no development environment beyond the editor in the view. Reuse across stations is copy and paste, so a fix has to be reapplied by hand to every copy.

Confirm two things before planning around them: that the platform and license permit Program objects in this deployment, and that the site owner permits compiled in station code as a matter of policy. A Program object is defensible for a contained calculation on one station that the same team will keep maintaining. It is a poor home for anything that has to outlive the person who wrote it.

What a module gives you that the other two cannot

A Niagara module is a JAR you build outside the station with the Niagara build tooling and install on the platform through Software Manager. Inside it you can define your own component types, views and services against the Baja API. Annotations such as NiagaraType and NiagaraProperty generate the slot boilerplate, so a component you wrote drags out of a palette and behaves like a stock one. Our platform pages for the Niagara SDK, the Workbench SDK, the Baja API and BajaScript set out what each of those layers exposes.

The jobs that require a module are specific: a component type other engineers will use on their own wiresheets, a custom view or web interface, code that needs third party libraries and unit tests, and versioning so a correction ships as a new module version rather than a manual edit on every station. Device and protocol integration also lands here, and it has a decision path of its own that our article on when you need a custom Niagara driver already covers.

The obligations are just as specific. A module is compiled against a Niagara version, so a platform upgrade means a rebuild and a retest. Module signing requirements are version and platform scoped, so check what the Niagara release and platform you are targeting enforce; where signing applies, a code signing certificate and somewhere safe to keep it are part of the plan. The source needs a named owner after handover, and you need a way to roll a bad version back off a live JACE.

Mixing the three on one station

The three are not exclusive, and the boundary between them is worth deciding rather than letting it form by accident. A component that ships in a module drags onto a wiresheet and links like any stock block, so custom code can sit inside a sequence a technician still reads as a wiresheet. That arrangement keeps the sequence legible: the computation is in code, the wiring is on the sheet where the next person will look for it.

The reverse causes trouble. Logic split across a wiresheet and a Program object with no visible boundary means reading the sequence takes two editors and prior knowledge of which one holds the part that matters. Name the component for what it computes, keep its inputs and outputs on the sheet, and leave a note on the parent folder saying where the code lives.

One constraint applies to any mix. A station moved to another host does not carry the modules it depends on, because those install on the platform through Software Manager, so a restored station will not run until its modules are present. Module source also sits outside the station database, so version control and a reproducible build belong in the deliverable.

Related service: Related service: Our Niagara Development page is the overview of the Niagara engineering work we take on, including wiresheet logic, in station code and module development.

Related service: custom Niagara module and driver development.

Full-Stack Niagara Development Expertise

Advanced Niagara N4 programming led by a Tridium-certified Niagara Full Stack Developer with NCPD Drivers and NCPD User Interface credentials. Credential verification is available upon request for qualified enterprise clients.

We support custom Niagara modules, custom drivers, Niagara SDK work, Workbench tools, BQL reporting, dashboards, APIs, database integrations, station health checks, BAS/BMS integrations, and Niagara modernization projects.