Skip to content

Range Codes

Every time-based query in Busroot, in the web app, the HTTP API and the SDK, takes its period as a range code: a short string such as TODAY, WEEK_2026_09 or RELATIVE_HOURS_24. The web app's date pickers build these codes for you; API and SDK callers pass them directly as the rangeCode parameter.

The format is {TYPE}_{...params}. The first segment is the range type, and the rest are type-specific parameters separated by underscores.

Absolute range codes

Format Example Description
TODAY TODAY Current production day
YESTERDAY YESTERDAY Previous production day
DAY_{YYYY}_{MM}_{DD} DAY_2026_02_24 A specific calendar day
WEEK_{YYYY}_{WW} WEEK_2026_09 A specific ISO week
MONTH_{YYYY}_{MM} MONTH_2026_02 A specific calendar month
QUARTER_{YYYY}_{Q} QUARTER_2026_2 A specific quarter (13 ISO weeks, or 14 for Q4 in 53-week years)
YEAR_{YYYY} YEAR_2026 A full ISO week year (52 or 53 weeks)
HOUR_{YYYY}_{MM}_{DD}_{HH} HOUR_2026_02_24_14 A specific hour
MINUTE_{YYYY}_{MM}_{DD}_{HH}_{mm} MINUTE_2026_02_24_14_30 A specific minute
CUSTOM_{from}_{to} CUSTOM_1772000000000_1772086400000 An arbitrary range between two Unix timestamps in milliseconds (not seconds). from must not be after to

A code must name a real period, or the API rejects it with 400 and error code invalidInput (field rangecode), and the SDK rejects it before sending:

  • Type names are upper case, and each code has exactly the parts shown above.
  • Numbers are zero-padded to the width shown (DAY_2026_02_05, not DAY_2026_2_5). The one exception is the week number, which can be written with or without the leading zero (WEEK_2026_09 or WEEK_2026_9).
  • Years run from 2020 to 2100. For CUSTOM_* both timestamps must fall in those years (UTC), and from must not be after to.
  • Dates and times must exist: DAY_2026_02_30, MONTH_2026_13 and HOUR_2026_02_24_24 are rejected.
  • Weeks run from 1 to the number of ISO weeks in that year (52 or 53). So WEEK_2026_53 is valid, but WEEK_2025_53 is not.
  • Quarters run from 1 to 4.
  • Relative codes must be one of those listed below.

Relative range codes

A rolling window ending now.

Code Meaning
RELATIVE_HOURS_1 Last 1 hour
RELATIVE_HOURS_4 Last 4 hours
RELATIVE_HOURS_6 Last 6 hours
RELATIVE_HOURS_12 Last 12 hours
RELATIVE_HOURS_24 Last 24 hours
RELATIVE_HOURS_48 Last 48 hours
RELATIVE_HOURS_72 Last 72 hours
RELATIVE_DAYS_7 Last 7 days
RELATIVE_DAYS_28 Last 4 weeks
RELATIVE_MONTHS_3 Last 3 calendar months
RELATIVE_MONTHS_6 Last 6 calendar months
RELATIVE_MONTHS_12 Last 12 calendar months. It still resolves for existing links and API callers, but the web app's pickers no longer offer it

The month-based relative codes step back by real calendar months (respecting month lengths and leap years), not by a fixed number of days.

How a code resolves

  • Everything resolves in the plant's timezone. A range is always interpreted where the plant is, never where the server or viewer is.
  • Ranges follow the local clock across daylight-saving changes. A day that contains a clock change is 23 or 25 hours long, and a week, month, quarter or year that contains one is an hour shorter or longer. Each range ends exactly where the next one starts, so no data falls between two ranges or is counted in both. Daily and weekly aggregation windows follow the same days.
  • dayStartHour moves the day boundary. A plant whose production day starts at 06:00 means DAY_2026_02_24 runs from 06:00 on the 24th to 06:00 on the 25th; TODAY and YESTERDAY respect the same offset, and WEEK_*, MONTH_*, QUARTER_* and YEAR_* apply it at their starting boundary. The day starts at 06:00 by the local clock on the days the clocks change too, so the 23- or 25-hour day is the production day the change falls in: with the clocks going forward at 01:00 on Sunday 29 March, DAY_2026_03_28 runs from 06:00 on Saturday to 06:00 on Sunday and is 23 hours. A day start inside the hour the clocks skip moves to the next hour that exists, on every path: daily aggregation windows put that 23-hour day on the same date as the DAY_* code.
  • weekStartDay moves the week boundary, and with it quarter and year boundaries, which are built from weeks.
  • Years are ISO week years, not calendar years. YEAR_2026 is the 52 or 53 ISO weeks of 2026, which keeps year and quarter boundaries aligned with WEEK_*. Around New Year this matters: 31 December 2024 belongs to ISO week 1 of 2025.
  • Aggregated queries snap inward. When a query also asks for an aggregation window (5m, 1h, 1d, 7d), the resolved start and end are snapped to whole windows (the start forward, the end backward), so the result only ever covers complete periods inside the range you asked for. A custom 06:00–11:30 at 1h resolves to 06:00–11:00, never 06:00–12:00. A CUSTOM_* code resolves exactly like the same custom range.
  • Relative codes at a daily or weekly window count whole production days or weeks. At 1d, RELATIVE_DAYS_7 is the 7 complete production days before the current one, and RELATIVE_HOURS_72 the 3 before it; at 7d, RELATIVE_DAYS_28 is the 4 complete weeks before the current one. This stays true across a clock change. At 1h and finer windows, a relative code is an exact number of elapsed hours.
  • The aggregation window must suit the range. Each range length allows a set of aggregation windows; the web app's dropdown only offers valid ones, and the API rejects a window outside the allowed set for the requested duration.

What the web app offers