Python Agent
I2C Sensors

I2C Sensors

The Plexus agent auto-detects I2C sensors connected to your device and streams their data. Install the sensors extra:

pip install plexus-agent[sensors]

Auto-Detection

The fastest way to get started. auto_sensors() scans your I2C bus, identifies connected sensors, and creates a preconfigured hub.

from plexus import Plexus
from plexus.sensors import auto_sensors
 
hub = auto_sensors()       # Scans I2C bus, finds all connected sensors
hub.run(Plexus())          # Start streaming to Plexus

This scans the default I2C bus (/dev/i2c-1), matches addresses to known sensors, and begins sampling at each sensor's default rate.

# Or use the CLI — does the same thing
plexus scan --setup
plexus run

Manual Configuration

If you want control over which sensors to use and their sample rates, configure the hub manually:

from plexus import Plexus
from plexus.sensors import SensorHub, MPU6050, BME280, INA219
 
hub = SensorHub()
hub.add(MPU6050(sample_rate=100))   # IMU at 100 Hz
hub.add(BME280(sample_rate=1))      # Environment at 1 Hz
hub.add(INA219(sample_rate=10))     # Power monitor at 10 Hz
 
hub.run(Plexus())

Configuration Options

All sensors (BaseSensor) accept these common parameters:

ParameterTypeDefaultDescription
sample_ratefloat10.0Samples per second (Hz). Some sensors override: SystemSensor defaults to 1 Hz, GPSSensor defaults to 1 Hz.
prefixstr""Prefix applied to all metric names from this sensor
tagsdict{}Tags applied to all metrics from this sensor

I2C sensor subclasses additionally accept:

ParameterTypeDefaultDescription
busint1I2C bus number
addressintsensor defaultOverride the I2C address
# Two MPU6050 IMUs on different addresses
hub.add(MPU6050(sample_rate=200, address=0x68, tags={"position": "left"}))
hub.add(MPU6050(sample_rate=200, address=0x69, tags={"position": "right"}))
 
# BME280 on bus 0 (older Pi models)
hub.add(BME280(bus=0))

Supported Sensors

SensorTypeMetricsInterface
MPU60506-axis IMUaccel_x/y/z, gyro_x/y/z0x68
MPU92509-axis IMU (6-axis active)accel_x/y/z, gyro_x/y/z0x68
BME280Environmentaltemperature, humidity, pressure0x76
INA219Current/Powerbus_voltage, shunt_voltage, current_ma, power_mw0x40
SHT3xTemp/Humiditytemperature, humidity0x44
BH1750Ambient Lightilluminance0x23
VL53L0XTime-of-Flightdistance_mm0x29
ADS111516-bit ADCchannel_0, channel_1, channel_2, channel_30x48
QMC5883LMagnetometermag_x, mag_y, mag_z, heading0x0D
HMC5883LMagnetometermag_x, mag_y, mag_z, heading0x1E
GPSGPS Receivergps_latitude, gps_longitude, gps_altitude, gps_speed_knots, gps_satellites, gps_hdopSerial
SystemSystem Healthcpu.temperature, cpu.usage_pct, cpu.load, memory.used_pct, memory.available_mb, disk.used_pct, disk.available_gb, net.rx_bytes, net.tx_bytes, system.uptime, system.processesN/A

All I2C sensors are detected by address during auto_sensors() or plexus scan. The GPS and System sensors use serial and OS interfaces respectively.

Custom Sensors

Build a driver for any I2C sensor by subclassing BaseSensor. Implement setup() and read():

from plexus.sensors import BaseSensor, SensorReading
 
class StrainGauge(BaseSensor):
    name = "StrainGauge"
    description = "Load cell strain gauge via ADC"
    metrics = ["strain", "force_n"]
 
    def read(self):
        raw = self.adc.read_channel(0)
        strain = (raw / 4096.0) * self.calibration_factor
        return [
            SensorReading("strain", round(strain, 6)),
            SensorReading("force_n", round(strain * self.k_factor, 2)),
        ]

Use your custom sensor like any built-in one:

from plexus import Plexus
from plexus.sensors import SensorHub
 
hub = SensorHub()
hub.add(StrainGauge(sample_rate=100, tags={"location": "beam-center"}))
hub.run(Plexus())

BaseSensor API

MethodDescription
setup()Called once on startup. Initialize hardware, calibrate.
read()Called at sample_rate Hz. Return a List[SensorReading].
cleanup()Called on shutdown. Optional. Release resources, set sensor to sleep mode.

Multiple Buses

If your device has more than one I2C bus, specify the bus number per sensor:

hub = SensorHub()
hub.add(MPU6050(bus=1, sample_rate=100))     # Bus 1 — IMU
hub.add(BME280(bus=3, sample_rate=1))        # Bus 3 — Environment

You can also pass the bus number to each sensor individually:

hub = SensorHub()
hub.add(BME280(bus=3))   # Uses bus 3
hub.add(INA219(bus=3))   # Uses bus 3

Next Steps

  • Sending Data — Send custom metrics alongside sensor data
  • CLI Reference — Use plexus scan to detect sensors from the terminal