All posts

Moving alarm routing out of tags

Tag-change scripts that fire texts and emails feel fast to build — until on-call rotations, escalation and acknowledgement turn them into a maintenance nightmare. Here's the pattern I reach for instead.

Why tag-change alarm scripts rot

When the notification logic lives inside a tag's value-changed script, a handful of things go wrong fast:

  • They fire on gateway restart and during tag-quality blips — paging people at 2 a.m. for nothing.
  • There's no shared idea of who is on call, so recipient lists get hard-coded in dozens of places.
  • No dedup and no escalation — the same alarm hammers the same phone.
  • They're nearly impossible to test without forcing live tag values.

A roster table plus one pipeline

Pull the routing out of the tags and into data. You want three things:

  • An on_call_roster table — shift, role, name, contact, effective dates.
  • Ignition's built-in Alarm Notification with on-call rosters and schedules, or — when you need custom logic — one gateway script that reads the roster and decides who gets what.
  • Alarms raised through the alarming system (deadbands, delays, priorities) instead of raw tag scripts.

A trimmed version of the lookup:

def current_oncall(area):
    rows = system.db.runNamedQuery("alarms/OnCallNow", {"area": area})
    return [r["contact"] for r in system.dataset.toPyDataSet(rows)]

What you get

  • One place to change the rotation — no redeploys.
  • A real audit trail of who was notified and when.
  • Testable logic: run the query in the Designer, no live process required.
  • Restart-safe: the pipeline owns delays and acknowledgement, not a tag event.

If your alarm story is a wall of tag-change scripts, this is usually the first thing I refactor.

Drowning in alarm scripts? I untangle Ignition alarm and notification setups for a living.

Contact us