Setup
Shop setup
Stations POST straight to this app. Add a customer, add a station, put that callback URL on GrokCallback.
First name
Used only in Ask greets on this seat. Blank is fine. Never on Dispatch, Export PDFs, or the sign-in page.
Company
Shows in the header on every page. Paste a logo URL or pick a small PNG.
How long to remember
Each score, PDF upload, chat rule, flag, and accepted call is kept this long, then dropped. The latest pack and score on a site stay. 0 = keep forever.
Station program
US Engineering installs the station program. It comes from the releases of the private callback repo (dn557/grokalytics-niagara-callback, latest v4.33). This app does not offer it for download. Set siteId, callbackUrl, and callbackToken from this app’s station page. Never paste callbackToken into chat.
Niagara Network vs BACnet
Same Program. Niagara.V4.29 splits the station across 15 one-minute Executes (quota = ceil(N/15)). maxPoints is the cap per POST, not per tick — 2000–5000. Do not one-shot 20000 — that POSTs HTTP 0. Skip junk (Local Device, Bacnet Comm, Monitor, Tuning Policies). pointFolder is slot:/Drivers — leaf devices under every driver (Niagara Conns, Bacnet RTU-1 / EF-1 / HWP-1, CylonBacnet, Modbus, WebCTRL, Lon, oBIX). walkMode niagara = Supervisor multi-driver. Niagara Conns pack first, then the other drivers. lastStatus says slice i/15 · pts · HTTP n. lastChunk on the last slice this tick. #7 re-reads null / fault / down in this slice only. lastWindow names the driver (BacnetNetwork/RTU-1+RTU-2+EF-1) — never an anonymous 0-5000 of all /Drivers. Foxs out. No setpoints. Never paste callbackToken. lastReport never carries Bearer.
Dual-driver Supervisor
Both Niagara Network and BACnet/IP (and Modbus / WebCTRL / anything else under /Drivers) on one Supervisor. One Program · one token · one siteId. Each minute posts the next slice (Niagara first). A large device can span slices. pointFolder is /Drivers — do not permanently narrow to BacnetNetwork/RTUs and do not flip walkMode.
- walkMode
- niagara (auto / dual / multi = same multi-driver walk)
- pointFolder
- slot:/Drivers
- skipDown
- true — local status only, no Fox ping
- maxPoints
- 2000–5000. Whole devices until this cap. One device over cap is packed whole + Soft.
- lastWindow names the driver — NiagaraNetwork/Site Y (whole Conn) then BacnetNetwork/RTU-1+RTU-2+EF-1. ExhaustFans / HotWater / Reheats land as leaf devices. Modbus / WebCtrl on a multi-driver peer.
- CylonBacnet, Modbus, WebCTRL, Lon, oBIX walk as first-class /Drivers/* roots — not a Bacnet-only branch.
- Empty folder = gap. The Program does not invent points. {err} 0 points is not site health. A network with zero walkable devices after junk-skip is omitted.
- Good lastStatus: {ok} 1070 points hook HTTP 200 station BacnetNetwork/RTU-1+RTU-2+EF-1 refresh ok=1040 stale=30 null=0 work NiagaraNetwork,BacnetNetwork devices=5 ticks=2/15 atomicA 4200-point Conn is packed whole with {soft} raise maxPoints — never window 0-2000 then 2000-4200 of the same device.
Niagara Network only
Customer A-class: one Supervisor, many JACEs, no BacnetNetwork sibling. One Program on the Supervisor only. Do not drop a second Program on a field JACE.
- walkMode
- niagara
- pointFolder
- slot:/Drivers/NiagaraNetwork
- maxPoints
- 2000–5000
- Down / fault / disabled / stale is skipped this tick.
- Bad lastStatus: {err} 0 connected walk targets — pointFolder is not a driver or Drivers folder.
BACnet IP (this box)
OnLogic / JACE with BACnet/IP devices and no Niagara Network children to page. Walk the folder that actually holds the points.
- walkMode
- folder
- pointFolder
- slot:/Drivers/BacnetNetwork
- maxPoints
- 2000–5000 — device-atomic fat windows. Sticky merge does not wipe a Niagara sibling.
- MS/TP under a Bacnet gateway = that driver’s children.
- Good lastStatus: {ok} 800 points hook HTTP 200 window BacnetNetwork/RTU-1+RTU-2 atomic
Every station (all three walks)
- callbackUrl = https://grokalytics.ai/api/ingest — no token in the URL.
- Use the name grokalytics.ai, never a vercel.app address or an IP; those change. A site firewall must allow grokalytics.ai by host name. This address stays public (no login page); the token protects it.
- callbackToken = that station’s token. An owner or admin presses Show token on the station page. The station sends it as a Bearer header.
- siteId must match the station you added in this app. A pack for any other id is rejected.
- HTTPS. lastStatus hook HTTP 200. HTTP 0 is connect fail — lastStatus is {err} packed HTTP 0, never {ok}. Cursor stays put until 2xx.
- Empty-target {err} still resets stationIndex to 0. If the same lastWindow repeats after HTTP 200, check junk-skip / pointFolder.
- One Program · one token · one siteId. Disable old duplicate Programs (Site U index-704 lesson). lastStatus / lastReport never contain callbackToken or Bearer.
- Tag units only (n:equip + one brick). Do not invent devices from setpoints. Path-key Correct only.
- Per-driver Tuning cheat-sheet: proxyExt pollFrequency + covIncrement stay companions this window. Tuning Policies folder is skip-junk (no stationIndex). historyExt doRecord when present. Subscribe each packed point every Execute. lastStatus includes refresh ok= stale= null=.
Accounts
Adding a seat only puts the email on the allow list. Email a set-password link sends one office-mail message with a single-use link. It does not open public sign-up. Text them yourself if mail is down: BAS Analytics — https://grokalytics.ai — sign in with the address you added.
Last online is the last time they used the app. Never if they have not been in.
Loading accounts…
Who is selecting issues
Flags, accepted calls, declined, Added To Next Maintenance, tickets, and work orders stamp the signed-in account. No shared shop name.
Signed-in account
1
This app
Customers → add the station. Copy the callback URL.
2
Station
US Engineering installs the station program from the private callback repo’s releases. Set siteId, callbackUrl, and callbackToken from this app’s station page. Dual-driver ships walkMode niagara and pointFolder slot:/Drivers. BACnet-only: set walkMode folder. Never paste callbackToken.
Station callback
Add the station in the app first. Then copy that station’s callback and token. A pack for an id you have not added is rejected.
- Ingest path
- https://grokalytics.ai/api/ingest
- Auth
- Authorization: Bearer <that station token>
Work order email
Every work order is emailed as plain text to this one address. It goes out from the same mailbox as sign-in emails. The email has the site, address, customer, unit, job number, priority, trade, problem, what the readings show, likely cause, next step, and who sent it. Only an admin can change the address. With no address, nothing is sent: the request is saved and a person follows up.
Callback contract
POST https://grokalytics.ai/api/ingest
Content-Type: application/json
Authorization: Bearer <token from that station page>
{
"siteId": "<exact station id you added>",
"readOnly": true,
"source": "GrokCallback",
"physicsVersion": "Physics.V2.2",
"niagaraVersion": "Niagara.V4.29",
"forceRefresh": false,
"tickId": "t…",
"slice": 1,
"sliceTotal": 15,
"lastChunk": false,
"hearOnly": false,
"dualWalk": true,
"pointCount": 80,
"points": [{ "name": "", "ord": "", "value": "", "slotType": "control:NumericPoint" }]
}
200 accepted · 404 unknown station · 401 bad token · 403 siteId mismatch