Skip to content

Building a custom report ​

/admin/report/dynamic: Reports → Custom Reports (the page itself is titled Dynamic Reports)

The fixed reports each answer one question. Custom Reports is for the question that is not on the list: pick a table, say which numbers you want and how to group them, run it, and save it so you can run it again next week.

It reads the same tables the fixed reports read, so the same units apply: a device is still a radio, a stay is still not a person. What you gain is the freedom to combine and group; what you do not gain is any new data. For a number nothing records yet, make one with a data table first.

What a custom report does with its table, in order A custom report reads one source table. It keeps the rows inside the date range, and the location or venue you chose when running it, on your organisation's clock. It applies up to ten filters, groups what is left by up to five dimensions, and works out up to twenty metrics per group with sum, average, minimum, maximum or count. The result is drawn as a table, line, bar, pie or gauge and can be exported as CSV. The example: Temperature and Humidity, last 30 days, source equals fixed, grouped by date and zone, average temperature. THE BUILDER, LEFT TO RIGHT1 · Sourceone table:a built-in one,or your owndata table2 · Rangedates, and alocation orvenue — onyour clock3 · Filtersup to 10:zone, device,a source, ora threshold4 · Group byup to 5:date, hour,zone, device,source …5 · Metricsup to 20, eacha field andsum · avg · minmax · countEXAMPLE — DAILY AVERAGE TEMPERATURE PER ROOM, WALL SENSORS ONLYTemperaturelast 30 dayssource = fixeddate, zoneavg temp.Shown asTable · Line · Bar · Pie · Gauge, then Export CSVSaved, it keeps its recipe, not its answer: opening it again runs it again on today’s data.
Filters act on the rows before they are grouped; metrics are then worked out once per group. So "average temperature, grouped by date and zone" is one average for each room on each day, made only from that room's rows on that day.

Who can do it. Viewing and running saved reports needs view-report-dynamic and execute-report-dynamic; making and changing them needs create-report-dynamic and edit-report-dynamic; deleting one needs delete-report-dynamic. As shipped, Admin has all five, Manager all but delete, and Viewer can run reports but not make them.

The page ​

The page opens on your saved reports, newest first, each with three buttons: Run Report (▶), Edit (pencil) and Delete. New Report (top right, or in the list's toolbar) opens the builder in a panel on the right. Running a report switches to its result: ← Reports goes back, Edit reopens the builder, Export CSV downloads what you are looking at, and the bar under the title holds Date Range, Location, Venue and Run.

The builder, top to bottom ​

1. Report Name and Description. Name it for the question: "Busiest hour at the lobby door", not "Report 3".

2. Source Table. One table per report:

TableWhat a row isNumbers you can ask for
Entry / Exitone counting gateway, one hourEntries, Exits
Devices Detectedone zone, one dayDevices detected (distinct). Group by Zone (below)
Footfall — devices once per placeone place at one level (zone, venue, location or the whole site), one day and one hourPeople (tags not bound to an asset), Assets (tags on assets), Devices (both together) and Tags (the same figure as Devices)
Loyalty / Repeatone place, one dayNew Visitors, Return (Recent), Return 1–4 Wk
Loyalty by place — every room a device was inone place at one level, one dayNew Visitors, Return (Recent), Return 1–4 Wk
Dwell Timeone place, one daythe dwell bands (< 15 min … 8+ hrs), Passby, Visit, Engaged
People Countone zone, one source, one hourPeople (the hour's peak), People (average of every reading)
Gender Entryone place, one dayMale, Female, Unknown Gender
Temperature / Humidityone sensor, one source, one hourTemperature, Humidity, Light (lux), Pressure (hPa)
Distance / RSSIone device at one gateway, one hourRSSI, Distance
Batteryone device, one hourBattery Level
Device Statusone device at one gateway, one hourCount (Records): hours heard
Noiseone sensor, one hourNoise (dBA)
Air Qualityone sensor, one pollutant, one hourReading
Button Pressesone pressCount (Records): presses
Your data tablesone firing of a rule (or a row added by hand)your number columns, and Count (Records) for the number of rows

3. Visualisation. Table, Line, Bar, Pie or Gauge. A table always works; a line wants a Date or Hour grouping; a pie wants one grouping and one metric; a gauge shows the first metric summed over every row, so it suits a single total.

4. Group By (Dimensions). Up to five; the counter shows how many you have picked. Date and Hour are on your organisation's clock. Location, Venue, Zone, Gateway MAC, Device MAC, Person / asset and Rule show names in the result and keep the id in the CSV. Some tables add their own: Source on Temperature (a fixed sensor or a roaming tag) and People Count (a counting sensor; gateway, the tags present, which is not a head count; or presence, an occupied-or-empty sensor, which is not a count at all); Level on Footfall and Loyalty by place (zone, venue, location or whole site); Status on Device Status; Pollutant and Unit on Air Quality (group or filter by pollutant before averaging, or CO₂ and PM2.5 are averaged together); Press type on Button Presses.

5. Metrics. At least one, up to twenty; Add for another. Each is a field and a function: sum, avg, min, max or count. Sum a count of things (entries); average a level (temperature, RSSI, battery); take the max of a peak (People (the hour's peak)). People (average of every reading) is always a true average of every reading in the period, whichever function you pick.

Only where. The filter button on a metric (funnel) opens a second line: only where a field equals (or not equals, less than, greater than, contains) a value. The metric then counts only those rows, while the other metrics on the report still count everything. That is how one row can hold both Count (Records) and Count (Records) only where Gender equals female. A filter (step 7) narrows the whole report; only where narrows one metric. Date and Hour cannot be used here; filter on them instead.

6. Calculated columns. Up to five; Add for another. Give the column a name, then pick two of the metrics above and how to combine them: minus, plus, times, divided by or as % of. It is worked out row by row from the same totals the table shows, after every month in the range is added together, and it appears in the table, the chart and the CSV under the name you gave it. A division by zero is left empty rather than shown as infinity.

7. Filters. Up to ten; Add for another. A field, an operator (equals, not equals, < less than, > greater than, contains) and a value: a zone, a device, a source, or a threshold (temperature greater than 30).

Then Save Report at the foot of the panel. It appears in the list; ▶ runs it.

Running it ​

  1. Press ▶ on the report.
  2. Set Date Range. Dates are whole days on your organisation's clock, the same days the fixed reports show.
  3. Optionally narrow to a Location and a Venue. (These apply to the built-in tables; a data table is narrowed with a filter instead.)
  4. Run. The chart and the Results table fill in; the result line says how many rows came back.
  5. Export CSV for the same rows in a spreadsheet, with ids beside the names.

Worked examples ​

Which hour of the day is busiest at the lobby door? Entry / Exit → sum Entries → group by Hour → filter Gateway MAC equals the lobby counter's MAC → Bar, last 30 days. Read it as crossings, not people: Mei Ling Tan stepping out for coffee and back is two entries.

Daily average temperature per room, from the wall sensors only. Temperature / Humidity → avg Temperature → group by Date, Zone → filter Source equals fixed → Line. Leave the source filter off and a tag in someone's pocket averages into the room.

How many men used the toilets, when only the women's side has a sensor? Northwind counts everyone at the toilet corridor door and has a motion sensor in the women's toilet; two rules fill the data table Toilet entries, one row per minute the door counted people (entry_total) and one row per women's visit (gender = female). Then: metric 1 sum Entry total; metric 2 count Records only where Gender equals female; calculated column Male visits = metric 1 minus metric 2, and Female share = metric 2 as % of metric 1; group by Hour; Bar. The answer is only as good as the two sensors: a motion sensor that fires several times in one visit overcounts women and undercounts men, so set the women's rule to Repeat at most every a few minutes (see Data tables).

How often did the Level 2 toilets get a visit, by hour? Your data table Toilet visits → sum visits → group by side and Hour → Bar, last 7 days. The table is filled by a rule; see Data tables. This is also the way to count how often a rule fired, grouped and charted: point an Add a row action at a table and report on it. (Each firing is also listed on Monitor → Live Monitor → Rules, but that list is not a report source.)

What to keep in mind ​

Group by changes what a count means. A device seen in three zones counts in each of them, so the same metric grouped by zone and by venue will not add up to the same figure. Neither is wrong; they are different questions.

Devices Detected must be grouped by Zone. It counts distinct devices per zone per day, and a device that went through four rooms is in four zones' day rows, so adding them up for a venue, a location or the whole organisation would count it four times; without a Zone grouping the report says so instead of running. (The table also holds hourly rows, but the builder does not offer Hour for it.) For venue, location or site totals use the Footfall table below, or Reports › Footfall.

Footfall and Loyalty by place read one level at a time. Each holds a row for every zone, venue and location a device was in that day, and one for the whole site, each counting the device once. A run reads one level: the finest place it is grouped or filtered by, or the whole site when it names no place. Group or filter by Level to choose. So Footfall grouped by Venue gives each venue's devices once per venue, however many of its rooms they went through. Footfall also has day rows and hour rows: group by Hour and you read the hourly rows, otherwise the day rows, never both. Loyalty by place counts a device-day in every room the device was in; the older Loyalty / Repeat table credits it only to the first room of the day, so use Loyalty by place for a zone or a venue.

People Count: peak and average, never the last reading. People (the hour's peak) is the most at once in each hour; People (average of every reading) averages every reading. Occupied-or-empty sensors only say whether anyone was in, so their rows are left out unless the report is grouped or filtered by Source; the result says so. Reports saved before October 2026 that name People Count (Last Reading) or (Hourly Peak) still run.

Two sources are never added. Temperature and People Count carry a Source: a fixed sensor in the room, or a roaming tag / the tags present. Group by source, or filter to one, before summing or averaging across it. For a real occupancy figure use Source equals sensor; the gateway rows are tags heard, and a person without a tag is not in them. See Occupancy: which number is which.

Saved reports re-run, they do not snapshot. Opening a saved report runs it again on today's data. If you need a fixed record, export the CSV.

A query has 30 seconds. Hourly tables over a year with five groupings can run out, and the run then stops with an error instead of a result. Narrow the range or drop a grouping.

Questions and problems ​

Nothing comes back (No data for the selected period). The table has no rows for that period (a place with no sensor, or dates before the sensor existed), or a filter names something that does not match. Filters compare against ids, so a zone filter wants the zone's uid and a gateway filter its MAC, which the fixed reports' CSVs carry.

The table I want is not in Source Table. A data table you have just made appears after you reload the page. Your data tables is not shown at all until you have made one.

An old report says "Rule Write Records" is retired. That source has had nothing written to it since rules began adding rows to data tables. Make a data table, point the rule's Add a row to a data table action at it, and build the report on that table under Your data tables.

The numbers are twice what I expected. A sum across two sources, a count grouped finer than you meant, or a Footfall sum across days (a device here every day counts once a day). Group by Source, or see Devices Detected above.

Times are off by some hours. They should not be: Date and Hour are on your organisation's clock, not your computer's. If they look wrong, ask your administrator to check the organisation's time zone.

Save Report is refused for a colleague. Their role can run reports but not make them (Viewer, as shipped). An Admin or Manager builds it; they can then run it. Only an Admin, as shipped, can delete a saved report.

→ Report glossary for every table's units · Reports for the fixed reports these tables feed.

Last updated:

Omaya platform documentation