Monitoring LiDAR Thermal States and Shot Limiting in Real Time via Ouster SDK

Hello community!

I wanted to share a Python script I put together for monitoring the thermal status of Ouster sensors.

While you can always poll the HTTP telemetry API to check sensor temperatures, polling too frequently can create unnecessary network and processing overhead. This script takes a different approach by reading the thermal flags embedded directly inside the incoming UDP LiDAR data packets.

By utilizing the PacketFormat class within the Ouster SDK, this script extracts the exact shot-limiting and thermal-shutdown states, as well as their respective countdown timers, directly from the packet stream.

Refer to:

This script has been fully tested and verified using the following environment:

Ouster SDK Version: 0.16.2

Sensor Firmware Versions: 3.1.0 and 3.2.0

#!/usr/bin/env python3

import argparse
import time
from contextlib import closing

from ouster.sdk import core, sensor


def enum_name(enum_cls, code: int) -> str:
    try:
        return enum_cls(code).name
    except Exception:
        return f"UNKNOWN({code})"


def main() -> None:
    parser = argparse.ArgumentParser()
    parser.add_argument("hostname", help="Sensor hostname or IP")
    parser.add_argument("--lidar-port", type=int, default=7502)
    parser.add_argument("--imu-port", type=int, default=7503)
    args = parser.parse_args()

    kwargs = {
        "timeout": 1.0,
        "buffer_time_sec": 1.0,
    }
    if args.lidar_port is not None:
        kwargs["lidar_port"] = args.lidar_port
    if args.imu_port is not None:
        kwargs["imu_port"] = args.imu_port

    with closing(sensor.SensorPacketSource(args.hostname, **kwargs)) as source:
        pf = core.PacketFormat(source.sensor_info[0])

        last_state = None

        for sensor_idx, packet in source:
            if not isinstance(packet, core.LidarPacket):
                continue

            shot_code = pf.shot_limiting(packet.buf)
            therm_code = pf.thermal_shutdown(packet.buf)

            shot_countdown = pf.countdown_shot_limiting(packet.buf)
            therm_countdown = pf.countdown_thermal_shutdown(packet.buf)

            state = (shot_code, therm_code, shot_countdown, therm_countdown)

            # Print on change, instead of spamming every lidar packet.
            if state != last_state:
                print(
                    f"{time.strftime('%Y-%m-%d %H:%M:%S')} "
                    f"shot_limiting={enum_name(core.ShotLimitingStatus, shot_code)}({shot_code}) "
                    f"shot_countdown={shot_countdown} "
                    f"thermal_shutdown={enum_name(core.ThermalShutdownStatus, therm_code)}({therm_code}) "
                    f"thermal_countdown={therm_countdown}"
                )
                last_state = state

            if shot_code != int(core.ShotLimitingStatus.NORMAL):
                print("WARNING: lidar is in, or approaching, shot limiting")


if __name__ == "__main__":
    main()

Sample Output of this script

python3 monitor_thermal.py 192.168.2.229
[2026-05-26 15:32:25.746] [ouster::sensor] [info] Opening port: 7502
[2026-05-26 15:32:25.746] [ouster::sensor] [info] Opening port: 7503
2026-05-26 15:32:25 shot_limiting=NORMAL(0) shot_countdown=0 thermal_shutdown=NORMAL(0) thermal_countdown=0
2 Likes