Skip to content

How Manifest Settings Drive Busroot

The Schema Reference says what each field is. This page says what it does — how each part of the configuration shapes what Busroot records, calculates and shows. It is worth reading before changing configuration on a live account, because several settings have effects that are not obvious from their names.

Time and calendar

A plant's timezone, dayStartHour and weekStartDay anchor every time-based calculation for its stations:

  • Every date range resolves in the plant's timezone. "Today", a named day, a week, a month, a quarter, a year — all are interpreted where the plant is, not where the server or the viewer is.
  • dayStartHour moves the day boundary. A factory whose day starts at 06:00 means "Tuesday" runs from 06:00 Tuesday to 06:00 Wednesday, in every report and dashboard. "Today" and "Yesterday" respect the same offset.
  • weekStartDay moves the week boundary, and with it the boundaries of quarters and years, which are built from weeks. Weekly and longer views for a plant that starts its week on Sunday genuinely start on Sunday.

Change these on an established plant with care: the boundaries of historical reporting periods move with them.

Shift patterns and OEE

Shifts decide when time counts. Production counts only need a running schedule (below), but utilisation, OEE and the station's live running/stopped state additionally require the time to fall inside a shift:

  • Outside shift hours a station reads out of shift and accrues no productive time, however much it is producing. Counts still record; the percentages don't move.
  • A station resolves its shift pattern from its own shiftPatternCode, or its group's if it doesn't set one. A station with no resolvable pattern is never in shift — it will show production counts and permanently zero utilisation. This is the most common surprise when commissioning a new station: if the numbers are all zero except the count, check the shift pattern first.
  • This is why a 24/7 shift pattern is the practical choice while commissioning — a test at any hour still produces figures. Realistic patterns can come later.

Station codes are permanent

A station's code is the key that ties everything recorded — production, downtime, utilisation, energy — to the station. Two consequences:

  • Renaming a code orphans the station's history. The data recorded under the old code is not deleted, but nothing will ever read it back. Treat a code change as decommissioning one station and creating another; change name for display instead.
  • Incoming device messages must use the station code exactly as it is spelled in the manifest. Signals are stored under the code as published on the MQTT topic, so a device publishing to station1 does not land data on a station whose code is STATION1.

Archived stations keep their history, and creating a new station with an archived station's code (case-insensitively) is rejected — so the historical data can never be silently claimed by a new station.

Station behaviour settings

These settings decide how raw device signals become "running", "down" and performance figures:

  • Running is decided by productiveStatusMode. With the default productive_signal, the station is productive while the device sends productive signals, each one holding the state for productiveHoldOnTime (so a machine that signals once per cycle stays "running" between cycles — set the hold-on to comfortably exceed the gap between signals). With electrical_usage or line_speed the station is running while the measured value is above the corresponding stopped-threshold. Production counts alone never make a station productive — a device that publishes only counts shows output and 0% utilisation until it also publishes a productive signal, or the mode is switched.
  • Down is decided by downtimeDetectionMode. In the common utilisation mode, a stop becomes a recorded downtime once it lasts longer than utilisationDowntimeThreshold (default 1 hour — usually worth lowering). In production mode the threshold derives from the SKU's cycle time and downtimeDurationThresholdMultiplier. off records no downtimes at all.
  • Speed signals pass through speedScale and speedOffset before display, so a sensor whose raw value doesn't match the real speed can be calibrated in configuration rather than in the device. speedToProductionRatio additionally converts speed into production counts for continuous processes that have no discrete unit signal.
  • Performance targets come from the running SKU's rate (cycleTime, unitsPerMinute or unitsPerHour) when it has one, falling back to the station's own rate fields. lineSpeedTarget switches the performance comparison to speed-vs-target.
  • Costs use the SKU's value per unit where set, with the station's idleCostPerMinute covering losses that can't be attributed to a SKU. electricalPowerNominalKw feeds the energy views' expected-usage comparisons.

Configuration vs runtime state

A handful of station fields — statusCode, statusCodeUpdatedAt, currentOperatorInitials, alertMessage, alertExpiresAt — are state Busroot writes, not configuration you author. They appear in the schema so the document is complete, but the live values are maintained by the platform as devices report and operators sign in and out. Setting them in a manifest achieves nothing lasting.

SKUs

  • A schedule may only name a SKU that already exists. Creating a schedule with an unknown SKU code is rejected — nothing creates the SKU for you. Add the SKU first, either in the admin UI or in a version-controlled manifest; keeping a permanent test SKU (e.g. CALIBRATION) in the list is normal practice.
  • value drives money. Lost-production cost and the cost of rejected (bad-quality) units are both units × value.
  • Rates drive targets. The SKU's cycleTime/unitsPerMinute/unitsPerHour set the ideal counts the performance and OEE figures compare against while a schedule for the SKU runs, and project schedule durations on the Gantt.
  • stationCodes / stationGroupCodes restrict scheduling — when set, only the named stations (or stations in the named groups) can be scheduled with the SKU.
  • allowUseInQuickSchedule controls whether operators can pick the SKU when starting an ad-hoc schedule from the tablet.

Reasons and the include/exclude cascade

A reason's type list decides where it is offered: downtime reasons when categorising stoppages, non-production reasons when scheduling planned non-production time, quality reasons when recording rejected units.

Which reasons a particular station offers is decided by the includeReasonCodes/excludeReasonCodes lists, evaluated level by level — account, then plant, then station group, then station:

  • No include list anywhere → every reason is available.
  • Any include list → the available set starts from the include lists: each level's includes are added (a lower level can re-add something a parent excluded).
  • Each level's excludes are then subtracted at that level, after its includes.

The same cascade, with the same semantics, controls which Tasks apply to a station via includeTaskCodes/excludeTaskCodes.

requireNotes on a reason works differently — it inherits down the reason tree, not the station hierarchy: a child reason that doesn't set it takes the nearest ancestor reason's setting, and false explicitly opts out. When it resolves on, operators must enter a note before the reason can be confirmed against a downtime.

Tasks

  • A frequency of schedule means the Task must be completed once per production schedule — it appears when a schedule starts and is missed if the schedule ends without it.
  • A frequency of cron means the Task is due at every cron fire, evaluated in the plant's timezone; the fire is the deadline. availableBeforeDeadlineMinutes controls how long before the deadline the Task appears on the tablet, so a weekly check due Friday 17:00 can be made available only from Friday morning.
  • Which stations a Task applies to follows the include/exclude cascade above; a SKU's taskCodes add SKU-specific Tasks whenever a schedule for that SKU runs.
  • Task lists are purely visual grouping — membership changes nothing about when or where a Task is due.
  • Task completion history records every instance as completed, missed or pending, so the audit trail exists whether or not operators tick things off.

Energy totals

By default a plant's or group's energy (kWh, cost, CO2) is the sum over its member stations. totalEnergyStationCodes replaces that: when set, the level's energy is the designated stations' energy instead — the physical meter's reading rather than the sum of sub-meters.

The designated stations are usually meter-only stations (enableMeterOnly), which exist to carry a physical meter's electrical signals and are hidden from production views. Group designations apply first, then the plant's own — so a plant total can legitimately differ from the sum of the group rows on screen, because it is a different physical measurement. Energy CSV exports include the meter stations as rows so the totals can always be reconciled.

Feature flags in practice

The flag table lists what each flag does; the cascade is what makes them practical at scale. Two worked examples:

  • Enable manual downtime for one plant only. Leave enableManualDowntime unset (off) at the account, set "on" on the plant. Every group and station in that plant inherits on; the rest of the account stays off.
  • Enable a feature everywhere except one station. Set "on" at the account, and "off" on the one station. The station's own value is the nearest defined one, so it wins over the account's.

Remember the default: a flag nothing sets is off. When a feature seems missing on a new account, check whether its flag was ever turned on at any level.