Skip to main content

Reports

The Reports page is the central place to define, preview, export, and email reusable reports.

Open Reports

Seven report types are available:

  • Unified Activity — a unified timeline across requests, access, alarms, automation, site modes, monitors, and scoped state changes.
  • Access Activity — who used an access point, when, how they authenticated, the result, and an optional event picture.
  • Device Health — uptime, current connection status, last seen time, disconnect count, and downtime.
  • Request Activity — commands, macros, API activity, users, results, and authorization denials.
  • Alarm Performance — alarm volume by severity, how long alarms took to acknowledge and resolve, what is still outstanding, and chronic repeat offenders.
  • Energy & Demand — daily consumption, production, grid import and export, net energy, peak day, and optional cost.
  • Stale Credentials — credentials that keep being refused, grouped by credential rather than by event.

Access Activity and Stale Credentials require the Access Control module in your license. When it is not licensed, the type appears in the Report type list marked not licensed and cannot be previewed, exported, or delivered. The other five types are always available.

Report definitions

A saved definition contains:

  • A stable name, display label, and description.
  • The report type.
  • Filters appropriate to the report type.
  • The columns to include.
  • A row limit and, for Access Activity, a picture limit.
  • An enabled flag, toggled from the header next to the saved-report picker. Clearing it stops every schedule on the report from delivering and blocks adding a new one, without deleting the definition or its history.

Definitions are declarative and validated by GEM. They do not contain SQL, JavaScript, or other executable code.

Access Activity reports can include:

  • Event time
  • User
  • Access point
  • Access method
  • Result
  • Reason
  • Matching access rule
  • Action
  • Facial-match result
  • A picture thumbnail, when the access event stored an image

Images are resized before preview or email delivery. Video and remotely hosted media are represented as links instead of being downloaded into the report.

Device Health reports can filter by device, current status, and a maximum uptime percentage. Uptime is measured from each device's first recorded connection sample, so a device with no data at the start of the period is scored over the window it actually has data for. The optional Measured From and Window Covered columns show that window, and the summary flags how many devices were measured over a partial one — see Device Health. Request Activity reports can filter by request type, request name, result, reason, user, client ID, or IP address. Raw request JSON is intentionally excluded from Request Activity reports because older payloads may contain credentials or tokens.

Unified Activity reports can filter by event kinds, zone or device scope, username, and matching text. They merge curated fields from several history stores; raw record bodies are intentionally excluded.

Stale Credentials

Rows are credentials, not events. Each row is one credential that was refused repeatedly over the period, with the refusal count, how many doors it was tried at and which, the first and last sighting, and how many days it has been active.

This answers a different question from Access Activity. A single refusal is a typo; the same credential refused over and over, across days and often across several doors, is a provisioning defect — a revoked worker, a rotated PIN nobody communicated, a code that was never pushed to one particular door. Every individual refusal looks unremarkable in the event log, which is why the pattern goes unnoticed until it is grouped.

FilterDefaultEffect
min_attempts3Minimum refusals for a credential to appear. Minimum 2 — at 1, every denial would qualify
multi_door_onlyoffOnly credentials refused at more than one door — a stronger signal than one person fumbling at their usual door
Access pointsallRestrict to specific doors
MethodallRestrict to pin, rfid, and so on

Sort by refusals, most recent, or door count.

Periods are previous 7 days, previous month, and previous day. A single day rarely holds enough refusals of one credential to clear the threshold, so the weekly and monthly windows are the useful ones. Schedule it weekly.

Credentials appear as a truncated fingerprint (#ad4482a7) that is stable across sightings, so the same code is recognizable from row to row. The code itself is never stored or displayed.

This is intentionally a report and not an alarm — it is a work item for whoever administers credentials, not something to wake anyone for. For the real-time counterpart, see PIN scanning.

Alarm Performance

Rows are alarm events that activated inside the report period. Available columns include activation time, alarm name, severity, target, attribute, lifecycle state, minutes to acknowledge, minutes to resolve, who acknowledged it, the triggering value, and the alarm message.

Filter by severity, lifecycle state, alarm name, zone or device scope, latched-only, and a minimum time the alarm stayed open. Sort by newest, oldest, slowest to acknowledge, or slowest to resolve.

Lifecycle state is derived when the report runs, not stored on the event:

StateMeaning
UnacknowledgedStill active, nobody has acknowledged it
AcknowledgedStill active, but acknowledged
ClearedNo longer active
ShelvedSuppressed until a future time

The summary reports mean time to acknowledge and mean time to resolve, the slowest of each, counts by severity, how many alarms are still open or unacknowledged, and definition/target pairs that fired more than once in the period. These are measured across every alarm matching the filters, not just the rows the row limit returns, so a capped report still reports accurate averages. Alarms that are still open have no resolve time yet and are excluded from the resolve average rather than counted as zero.

Energy & Demand

Rows are whole local calendar days. Available columns include the day, consumed kWh, produced kWh, grid import and export kWh, net kWh, estimated cost, the number of meters contributing, and how many days the row covers.

Filter by energy role (consumed, produced, grid import, grid export), by circuit/zone or meter device, and optionally supply a cost per kWh to add an estimated-cost column and summary card. Net energy is consumed minus produced, so a negative net means the site produced more than it used.

This report reads the daily energy history GEM banks at each local-midnight rollover, because the underlying meter attributes are cumulative lifetime counters — a day's usage only exists as the difference between two daily snapshots. Two consequences:

  • Today never appears. A day becomes reportable after its rollover. The available periods are previous day, previous 7 days, and previous month.
  • History starts when the rollup does. Days before this version was installed were never banked and cannot be reconstructed.

If the controller was offline across one or more rollovers, the energy that accumulated during the outage is banked against the day the outage started, and the Days Covered column and Gap Days card show how many days that row actually spans — so a gap is visible rather than quietly under-reporting.

Preview and export

Choose a start and end time, then click Run Preview. The report uses a half-open time range: the start is included and the end is excluded. This prevents an event from appearing twice when consecutive report windows meet at the same time.

Click Export CSV to download the current report. Pictures are not embedded in CSV files.

A cell whose value begins with =, +, -, @ or a tab is written with a leading apostrophe. Report values are not typed by an operator — device names, attribute values and request-log fields arrive from the network — and a spreadsheet treats those characters as the start of a formula. The apostrophe makes the sheet display the text instead of evaluating it; it applies to both the download and the CSV email attachment.

A cell that is entirely a number is exempt, so negative values stay numeric. -12.4, -1.5e-7 and +5 export as themselves and open as numbers; anything with a tail after the leading character — -1+1, =SUM(A1:A2), @cmd — is still neutralized. This matters most on Energy & Demand, where Net kWh and Estimated Cost go negative on any site that produces more than it draws, and on sub-zero temperature and alarm threshold columns. Earlier versions quoted those as text, which broke charting in the sheet and anything downstream that parsed the file.

Use Send Now to email the current report and time range to one or more comma-separated recipients. This is useful for testing the layout before enabling a schedule.

Send Now is narrower for a non-elevated role

Sending a report is an admin function, but a role can be granted it by name — the usual case being "let the front desk re-send the daily door summary". That grant is deliberately limited to re-sending a saved definition to the recipients stored on its schedule. A non-elevated caller cannot name a report type, a date range or a recipient of its own; without a saved definition to send, the request is refused. An elevated session is unrestricted. See Roles.

Where a preview row carries the id behind a name — the device on a Device Health row, the access point on an Access Activity row — the device name is a link that opens that device in a reference modal over the page, so following it up doesn't cost you the report definition, filters, or the preview you just ran. Rows that only record a target name (Unified Activity, Alarm Performance) are plain text.

On an Access Activity preview, click View Event to open the investigation dialog. It shows full event details, facial-match information, stored image or video, and can request a historical NVR snapshot when the event has no stored picture. Inside the dialog, the Access point and a macro-backed Action are likewise links that open the device or macro in the reference modal.

For Device Health, Request Activity, and Alarm Performance, click Open Operational View to open the corresponding operational page. Device Health and Request History receive the report's time range and applicable filters; Alarm Performance opens the Alarms console, which shows live state rather than a period and so takes no range; when the report filters on a single alarm definition, it opens the Definitions tab filtered to that definition rather than the unscoped console. The Device Health and Request History pages also have Create Report buttons that carry their current filters back into a new report definition.

Unified Activity and Access Activity are already their own investigation views, and Energy & Demand reads a daily rollup with no live equivalent, so those three have no separate operational page.

Email schedules

A saved report can have multiple schedules for different audiences or cadences. Each schedule includes:

  • A five-field cron expression, such as 0 7 * * * for 7:00 AM daily.
  • An IANA timezone, such as America/Chicago.
  • A period: previous day, rolling 24 hours, today, previous 7 days, or previous month. Each report type offers only the periods that make sense for it — Energy & Demand omits rolling 24 hours and today because it reports whole banked days. Previous month is a true calendar month, not a fixed 30 days, so a monthly delivery lines up with the month being compared. For a monthly energy email, pair previous month with the rule 0 6 1 * * (6:00 AM on the first of each month).
  • One or more email recipients.
  • A delivery format: Formatted email renders the rows as a table in the message body, or CSV attachment sends a short summary in the body with the rows attached as a .csv file named after the report.
  • Options to include pictures for Access Activity, send an empty report, and override notification-profile quiet hours.

Pictures are never included in a CSV delivery, so the include-pictures option is hidden when the format is CSV. A schedule created before delivery formats existed continues to send formatted email.

The default daily pattern sends the complete previous local calendar day at 7:00 AM. Calendar-day ranges account for daylight-saving changes rather than assuming every day is exactly 24 hours.

GEM records every scheduled and manual delivery attempt. The delivery history shows status, row count, recipient count, and any error. A missed scheduled run is caught up once after a server restart, and duplicate delivery for the same schedule period is prevented.

Creating reports with the AI assistant

Click Ask AI to build a report, or ask the admin assistant directly. Describe the report type, filters, columns, recipients, and delivery cadence you need.

The assistant can:

  1. Choose among Unified Activity, Access Activity, Device Health, Request Activity, Alarm Performance, Energy & Demand, and Stale Credentials.
  2. Resolve named users, devices, and access points.
  3. Preview a proposed report without exposing picture bytes or raw request payloads to the AI.
  4. Explain the proposed filters, delivery format, and schedule.
  5. Create the report and schedule after confirmation.

AI-created reports use the same validation and report registry as reports created in the page. The assistant cannot generate or execute arbitrary report SQL.

Data retention

Reports query their source history at run time; they do not make a separate permanent copy of event rows or pictures. If data retention removes an access event, Request History row, alarm event, or connection-history row, future reports cannot include it.

Energy & Demand is the exception: it reads the Daily Energy aggregate rather than raw history, which is why its retention default is three years. Pruning that store removes the ability to compare against last month or last year.

Delivery history is itself a retained store — see Report Runs on the Data Retention page, which keeps 180 days by default. Saved definitions and their schedules are configuration and are never pruned.