# Realtime Calibration

The **PIR Zeroing** (Realtime Calibration) feature enhances the Butlr Calibration System by automatically detecting when rooms are empty using Passive Infrared (PIR) motion sensors. This automated approach generates zero-occupancy calibration points without manual intervention, significantly improving the accuracy of occupancy tracking by correcting sensor drift more frequently throughout the day.

## Overview

PIR Zeroing leverages the motion detection capabilities of PIR sensors to identify periods when a room is unoccupied. When all PIR-enabled sensors in a room detect no motion for a configurable duration, the system automatically creates a calibration point marking that time as zero occupancy. This complements existing calibration methods by providing additional correction points between manual counts and operational day boundaries.

{% hint style="info" %}
**Automatic Activation**: PIR Zeroing works seamlessly with the calibration system when enabled. Simply set `calibrated: "true"` in your API requests and configure PIR settings for your rooms and sensors.
{% endhint %}

{% hint style="warning" %}
**Sensor Mode Requirement**: PIR Zeroing only works with sensors in "presence" mode. Sensors in "traffic" mode are not used to generate no-motion events for PIR zeroing.
{% endhint %}

{% hint style="success" %}
**Key Benefits**

1. **Automated Drift Correction:** No manual counts needed for zero-occupancy calibration
2. **Increased Accuracy:** More frequent calibration points throughout the day
3. **Flexible Configuration:** Customizable thresholds and time windows per room
4. **Graceful Degradation:** System continues working if PIR data is unavailable

**Important Note:** PIR Zeroing requires both room-level and sensor-level configuration. All eligible sensors must agree on absence for calibration points to be generated.
{% endhint %}

***

## How PIR Zeroing Works

### Motion Detection Process

PIR sensors continuously monitor for human presence by detecting infrared radiation changes. The system analyzes this data to identify absence periods:

1. **Sensor Monitoring**: PIR sensors report confidence values (0.0 to 1.0) indicating motion detection
2. **Absence Detection**: Values below the configured threshold indicate no human presence
3. **All-Sensor Agreement**: All PIR-enabled sensors in a room must show absence simultaneously
4. **Duration Validation**: Absence must persist for the configured time window
5. **Calibration Point Generation**: System creates a zero-occupancy point at the start of the absence period

The system includes sophisticated logic to prevent incorrect zero-occupancy calibration:

**Scenario**: PIR sensors may incorrectly detect absence while people are still exiting the room.

**Solution**: The drift correction algorithm analyzes occupancy patterns after PIR zero points. If it detects exit events (negative occupancy changes) immediately following a PIR zero point, it recognizes this as a false positive and excludes that calibration point from processing.

**Result**: Only valid empty-room periods generate calibration points, maintaining data integrity.

***

## Configuration

PIR Zeroing is configured through four GraphQL fields that control its behavior at both room and sensor levels.

### Room-Level Configuration

#### `pir_zero_enable` (Boolean)

Controls whether PIR Zeroing is active for a specific room.

* **Type**: Boolean
* **Default**: `false`
* **Description**: When `true`, the room will use PIR motion data to generate zero-occupancy calibration points

#### `pir_zero_threshold` (Float)

Sets the confidence threshold below which sensors indicate no human presence.

* **Type**: Float (0.0 to 1.0)
* **Default**: `0.05`
* **Description**: PIR sensor values below this threshold indicate absence. Lower values are more conservative.

#### `pir_zero_window` (Integer)

Defines how long all sensors must show absence before generating a calibration point.

* **Type**: Integer (seconds)
* **Default**: `300` (5 minutes)
* **Description**: Minimum duration of continuous absence required. Longer windows reduce false positives.

### Sensor-Level Configuration

#### `pir_zero_enable` (Boolean)

Controls whether a specific sensor participates in PIR Zeroing.

* **Type**: Boolean
* **Default**: `true`
* **Description**: When `false`, this sensor will be excluded from PIR-based calibration calculations

***

## API Usage Example

When PIR Zeroing is configured, it automatically enhances calibrated queries. Here's a complete example:

**POST** `https://api.butlr.io/api/v3/reporting`

```json
{
  "window": {
    "every": "5m",
    "function": "median"
  },
  "filter": {
    "start": "2025-01-20T00:00:00Z",
    "stop": "2025-01-21T00:00:00Z",
    "measurements": ["traffic_room_occupancy"],
    "calibrated": "true",
    "rooms": {
      "eq": ["room_id"]
    }
  },
  "group_by": {
    "order": ["time"]
  },
  "includeCalibrationPoints": true
}
```

**Response with PIR-generated calibration points:**

```json
{
  "data": [
    {
      "time": "2025-01-20T00:00:00Z",
      "value": 0,
      "room": "room_id"
    },
    // ... occupancy data ...
  ],
  "calibrationPoints": [
    {
      "timestamp": "2025-01-20T00:00:00Z",
      "occupancy": 0,
      "type": "operational_day_start"
    },
    {
      "timestamp": "2025-01-20T10:30:00Z",
      "occupancy": 0,
      "type": "pir_zero"  // PIR-generated calibration point
    },
    {
      "timestamp": "2025-01-20T14:15:00Z",
      "occupancy": 0,
      "type": "pir_zero"  // Another PIR-generated point
    },
    {
      "timestamp": "2025-01-21T00:00:00Z",
      "occupancy": 0,
      "type": "operational_day_end"
    }
  ]
}
```

***

## Best Practices

### Configuration Guidelines

1. **Start Conservative**: Begin with default settings (threshold: 0.05, window: 300 seconds)
2. **Monitor Results**: Use `includeCalibrationPoints: true` to verify PIR zero points are being generated
3. **Adjust Gradually**: If too few points are generated, try:
   * Increasing threshold to 0.1 (less conservative)
   * Decreasing window to 180 seconds (3 minutes)
4. **Room-Specific Tuning**: Different room types may need different settings:
   * Conference rooms: Shorter windows (180-300 seconds)
   * Open offices: Longer windows (600-900 seconds)

### Sensor Placement

For optimal PIR Zeroing performance:

* Ensure complete room coverage with PIR sensors
* Avoid sensor blind spots near exits
* Position sensors to detect all areas where people might be stationary
* Test sensor coverage by walking through all room areas

### Troubleshooting

**No PIR calibration points generated:**

* Verify `pir_zero_enable` is `true` for both room and sensors
* Check that sensors are in "presence" mode, not "traffic counting"
* Confirm PIR sensors are detecting motion correctly
* Review threshold and window settings

**Too many false positives:**

* Increase the time window (e.g., from 300 to 600 seconds)
* Decrease the threshold (e.g., from 0.05 to 0.02)
* Check for sensor placement issues or environmental interference

**Partial sensor agreement:**

* Ensure all sensors in the room have consistent PIR settings
* Verify sensor coverage overlaps appropriately
* Check for faulty sensors showing constant absence or presence

***

## Technical Details

### Processing Pipeline Integration

PIR Zeroing integrates seamlessly into the calibration processing pipeline:

1. **Room-Level Processing**: Only applies to `traffic_room_occupancy` measurements
2. **Configuration Check**: System verifies room has `pir_zero_enable: true`
3. **Sensor Filtering**: Identifies sensors with `pir_zero_enable: true` and `mode: "presence"`
4. **Data Query**: Retrieves PIR sensor data for the query time range
5. **Absence Analysis**: Identifies periods where all sensors show values below threshold
6. **Point Generation**: Creates calibration points with `type: "pir_zero"`
7. **Standard Processing**: Continues with normal calibration pipeline
8. **Standard Processing**: Continues with normal calibration pipeline

***

## Calibration Point Types

When using `includeCalibrationPoints: true`, the API returns calibration points with the following types:

| Type                  | Description                                 | Source       |
| --------------------- | ------------------------------------------- | ------------ |
| `user_provided`       | Explicitly provided via API request         | Manual input |
| `pir_zero`            | Generated from PIR sensor absence detection | Automatic    |
| `operational_day_end` | End of operational day (historical days)    | Automatic    |

***

## Limitations and Considerations

### Current Limitations

1. **Room-Level Only**: PIR Zeroing only works with `traffic_room_occupancy`, not floor-level measurements
2. **Presence Mode Required**: Sensors used to collect PIR data for zeroing must be in presence mode
3. **All-Sensor Agreement**: All enabled sensors must agree on absence
4. **Historical Data**: PIR Zeroing only affects data from when the sensors began collecting PIR data. This is configured by support independently of any other parameters discussed in this guide

### Future Enhancements

Planned improvements include:

* Machine learning-based threshold optimization
* Cross-validation with other sensor types
* Real-time calibration point generation
* Advanced pattern recognition for improved accuracy

{% hint style="info" %}
For general calibration information, refer to the [Calibration Overview](https://docs.butlr.io/historical-occupancy/reporting-api-overview/calibration-overview) documentation.
{% endhint %}
