Skip to content

Sensor Calibration

Observium can automatically calculate and apply sensor alert thresholds based on observed operating data. Rather than relying on vendor defaults or manual guesswork, calibration analyses historical RRD data for each sensor and sets thresholds that reflect real-world behaviour, with a configurable safety margin.

Calibration can be scheduled automatically for eligible sensors, applied manually from the web UI, or run from the command line.

Subscription Feature

Sensor auto-calibration is included in the Subscription Edition of Observium.


How Thresholds Are Calculated

Calibration collects the minimum, maximum, and average sensor reading over a historical period (default: 7 days) from the sensor's RRD file. It then calculates an adaptive margin and places thresholds outside the observed operating range:

Threshold Description
High Critical observed_max + margin
High Warning observed_max + margin/2
Low Warning observed_min - margin/2
Low Critical observed_min - margin

Threshold Direction

Calibration can operate in one of three directions:

  • both: set both high and low thresholds
  • high: set only high warning and high critical thresholds
  • low: set only low warning and low critical thresholds

If you do not explicitly choose a direction, Observium uses the default direction for the sensor class. For example, many classes such as temperature, current, power, load, and capacity default to high, while humidity, voltage, and fanspeed default to both, and runtime defaults to low.

This means that some sensors will not receive all four thresholds unless you explicitly override the direction in the UI or CLI.

Adaptive Margin

The margin is calculated per sensor class. For most classes it is the larger of two values:

  • Range margin: a percentage of the observed operating range (max - min)
  • Adaptive minimum: a percentage of the current sensor value, which prevents vanishingly small margins on very stable sensors

This ensures that a sensor with a 1 C variation over 7 days still gets a meaningful threshold gap, rather than thresholds separated by fractions of a degree.

Some sensor classes such as dbm, snr, attenuation, and sound use fixed absolute minimums instead, because percentage-of-value margins are not useful on logarithmic scales.

Thresholds are rounded before being written so that the stored values match the scale of the sensor.


Automatic Calibration Scheduling

Auto-calibration scheduling is controlled by $config['sensors']['auto_calibration']['mode']:

  • none (default): disable automatic scheduling
  • all: schedule calibration for all eligible sensors
  • auto_only: schedule only sensors discovered with automatic or default thresholds

When auto-calibration scheduling is enabled, sensors are scheduled for calibration after a learning period (default: 7 days). The process is:

  1. Sensor is discovered and auto_calibrate_after is set to now + learning_days
  2. Each later discovery run checks whether the learning period has elapsed
  3. Once the date is reached, calibration runs during discovery
  4. On success, thresholds are applied and the sensor is marked as auto-calibrated
  5. Auto-calibrated thresholds are protected from later discovery updates

Scheduling can apply to both newly discovered sensors and existing unscheduled sensors that still qualify.

Note

Automatic calibration is skipped for ignored or deleted sensors, sensors with manual thresholds, and sensor classes listed in skip_classes.

If calibration fails, Observium retries once per day up to max_retries times before giving up. A log event is recorded when a sensor is abandoned.


Manual Calibration via the Web UI

Single Sensor

For users with admin-level access, the current thresholds on sensor tables are clickable. Clicking the thresholds opens the calibration modal, which shows:

  • Historical statistics for the selected period: minimum, maximum, average, and range
  • A graph with current and proposed thresholds overlaid
  • A threshold comparison table showing current, proposed, and delta values
  • The calculated margin and how it was derived

You can preview the proposed thresholds before applying them.

Applying calibration from the modal marks the sensor's thresholds as manual, which prevents future auto-calibration from changing them.

If the sensor already has custom or manual thresholds, the modal still opens and applying calibration replaces the current thresholds with the newly calculated values.

Bulk Calibration

The Calibration view, accessible from the sensor table navbar or the health page navbar, shows all sensors for a device or globally, with checkboxes for bulk selection.

From the calibration view you can:

  • Select individual sensors using row checkboxes, use the table header checkbox for select all or none, or use Select Problems
  • Choose the historical period to use: 7 days, 30 days, or 90 days
  • Choose direction and margin preset for the preview and apply actions
  • Click Preview Selected to open a preview modal showing proposed thresholds for all selected sensors, with per-sensor Apply buttons
  • Click Apply Selected to apply calibration to all selected sensors with a progress indicator

Command Line Tool

The sensor-calibrate.php script provides preview and apply workflows suitable for scripting and scheduled tasks.

Text Only
USAGE:
  sensor-calibrate.php [OPTIONS]

OPTIONS:
  --help                     Show this help
  -h <device>                Calibrate sensors for specific device ID or hostname
  -s <sensor_id>             Calibrate specific sensor ID
  -c <sensor_class>          Calibrate sensors of specific class
  -p <period>                Historical period to analyse (default: 7d)
  -d <direction>             Threshold direction override: both, high, low
  -m <preset>                Margin preset: tight (0.5x), normal (1.0x), loose (2.0x)
  -a                         Apply calculated thresholds (default: preview only)
  -v                         Verbose output
  -n                         No prompts (non-interactive mode)

If -d is omitted, the script uses the default direction for the sensor class. Use -d both if you want to force both high and low thresholds for a class that normally calibrates only one side.

Examples:

Bash
# Preview calibration for all sensors on device 1
php sensor-calibrate.php -h 1

# Preview using hostname
php sensor-calibrate.php -h switch01.example.com

# Apply calibration to a single sensor
php sensor-calibrate.php -s 123 -a

# Preview all temperature sensors using 30 days of data
php sensor-calibrate.php -c temperature -p 30d

# Apply fan speed calibration for a device non-interactively
php sensor-calibrate.php -h 1 -c fanspeed -a -n

# Apply high-only thresholds with loose margins
php sensor-calibrate.php -s 123 -d high -m loose -a

# Force both sides for a class that normally defaults to high-only
php sensor-calibrate.php -c temperature -d both -a

Without -a, the script only previews proposed thresholds without modifying anything. This is safe to run at any time for review.

Applying with -a marks the thresholds as manual, just like applying from the web UI.


Configuration

All auto-calibration settings live under $config['sensors']['auto_calibration'] in config.php.

Global Settings

Option Default Description
mode 'none' Auto-calibration scheduler mode: none, all, auto_only
learning_days 7 Days to observe a new sensor before calibrating
skip_classes ['state'] Sensor classes to never auto-calibrate
max_retries 30 Maximum retry attempts before giving up on a failed calibration

Example: enable scheduler for auto-threshold sensors, extend learning period, and skip humidity

PHP
1
2
3
$config['sensors']['auto_calibration']['mode']          = 'auto_only';
$config['sensors']['auto_calibration']['learning_days'] = 14;
$config['sensors']['auto_calibration']['skip_classes']  = ['state', 'humidity'];

Per-Class Threshold Settings

Margin behaviour is configured per sensor class. The following keys are supported:

Key Description
margin Operating range multiplier for the critical threshold margin
adaptive_min_percent Minimum margin as a percentage of current sensor value
max_margin_ratio Cap margin at this multiple of sensor value
fallback_min Absolute minimum margin
min_high Fixed absolute minimum for high-threshold margins
min_low Fixed absolute minimum for low-threshold margins

Default per-class settings:

Class margin adaptive_min_percent Notes
current 20% 5% SI-range adaptive
voltage 20% 5% SI-range adaptive
power / apower / rpower 25% 5% SI-range adaptive
frequency 10% 2% Tight, mains frequency is usually very stable
temperature 50% 5% Wide range margin with 1 degree absolute fallback
fanspeed 30% 3% 100 RPM absolute fallback
humidity / load / capacity 15-20% 3-5% Percentage-based sensors
dbm / snr / attenuation 20% - Fixed absolute minimums
wavelength 10% 1% Very tight, wavelengths are stable
default 20% 5% Applied to unrecognised classes

To override a class, add an entry to config.php:

PHP
1
2
3
4
5
$config['sensors']['auto_calibration']['thresholds']['temperature'] = [
    'margin'               => 0.30,
    'adaptive_min_percent' => 3.0,
    'fallback_min'         => 0.5,
];

Threshold Protection and Recalibration

Calibration respects existing threshold state, but the protection rules are different for automatic and manual workflows:

  • Auto-calibration skips sensors that already have manual thresholds or custom limits
  • Thresholds applied via the web UI modal are marked as manual and protected from future auto-calibration
  • Thresholds applied via the CLI tool with -a are also marked as manual
  • Thresholds applied by automatic background calibration are marked as auto-calibrated and protected from later discovery overwrites
  • Manual recalibration from the web UI or CLI can replace existing thresholds, including thresholds that were already custom or manual

If you want a sensor to be eligible for automatic scheduling again, clear its manual protection or calibration state and let discovery schedule it again.


Troubleshooting

Sensor shows no proposed thresholds in the modal

The sensor has insufficient RRD data for the selected period, or its RRD file does not yet exist. Try a shorter period or wait for more polling data to accumulate.

Auto-calibration never fired for a new sensor

Check that $config['sensors']['auto_calibration']['mode'] is not 'none', the sensor class is not in skip_classes, and discovery is running regularly. Calibration is triggered during discovery, not polling.

Thresholds seem too wide or too narrow

Adjust the margin and adaptive_min_percent values for the relevant sensor class in config.php. Use a longer period such as -p 30d if you want the thresholds to reflect a broader operating history.

Auto-calibration was abandoned

The sensor failed calibration max_retries times. Common causes are a missing RRD file or persistent data quality issues. Investigate with sensor-calibrate.php -s <id> -v.

Manual calibration from the web UI or CLI still works and applies thresholds immediately, but it does not reschedule the abandoned background job. If you want the scheduler to try again later, reset the sensor's calibration state and let discovery schedule it again after the underlying problem is fixed.