设备控制 API
Device Control Client
- class neoruntime_ipc_sdk.device.DeviceStatus(soc_temp_c: 'float', mcu_temp_c: 'float', light_sensor: 'int', ptz_pan_pos: 'int', ptz_tilt_pos: 'int', zoom_pos: 'int', focus_pos: 'int', autofocus_enabled: 'bool', ircut_mode: 'IrCutMode', white_light_level: 'int', ir_led_on: 'bool', mcu_version: 'str', mcu_uptime_ms: 'int')[source]
Bases:
object- soc_temp_c: float
- mcu_temp_c: float
- light_sensor: int
- ptz_pan_pos: int
- ptz_tilt_pos: int
- zoom_pos: int
- focus_pos: int
- autofocus_enabled: bool
- ircut_mode: IrCutMode
- white_light_level: int
- ir_led_on: bool
- mcu_version: str
- mcu_uptime_ms: int
- __init__(soc_temp_c, mcu_temp_c, light_sensor, ptz_pan_pos, ptz_tilt_pos, zoom_pos, focus_pos, autofocus_enabled, ircut_mode, white_light_level, ir_led_on, mcu_version, mcu_uptime_ms)
- class neoruntime_ipc_sdk.device.DeviceEvent(type: 'EventType', timestamp_ns: 'int', gpio_pin: 'int' = 0, gpio_value: 'bool' = False, light_sensor_value: 'int' = 0, temperature: 'float' = 0.0)[source]
Bases:
object- class EventType(value)[source]
Bases:
Enum- GPIO_CHANGE = 0
- LIGHT_SENSOR_CHANGE = 1
- TEMPERATURE_ALERT = 2
- PTZ_MOVE_COMPLETE = 3
- FOCUS_COMPLETE = 4
- type: EventType
- timestamp_ns: int
- gpio_pin: int = 0
- gpio_value: bool = False
- light_sensor_value: int = 0
- temperature: float = 0.0
- __init__(type, timestamp_ns, gpio_pin=0, gpio_value=False, light_sensor_value=0, temperature=0.0)
- class neoruntime_ipc_sdk.device.AfJob(accepted, job_id, message)[source]
Bases:
objectResult of starting an autofocus job (native AF RPCs).
- accepted: bool
- job_id: int
- message: str
- __init__(accepted, job_id, message)
- class neoruntime_ipc_sdk.device.AfStatus(job_id, operation, state, progress, busy, anchor_valid, requested_ratio, effective_ratio, zoom_pos, focus_pos, best_focus, metric, confidence, reproducibility, estimated_distance_m, elapsed_ms, error_code, message)[source]
Bases:
objectFull snapshot of the autofocus engine state.
- job_id: int
- operation: str
- state: str
- progress: float
- busy: bool
- anchor_valid: bool
- requested_ratio: float
- effective_ratio: float
- zoom_pos: int
- focus_pos: int
- best_focus: int
- metric: float
- confidence: float
- reproducibility: float
- estimated_distance_m: float
- elapsed_ms: int
- error_code: int
- message: str
- __init__(job_id, operation, state, progress, busy, anchor_valid, requested_ratio, effective_ratio, zoom_pos, focus_pos, best_focus, metric, confidence, reproducibility, estimated_distance_m, elapsed_ms, error_code, message)
- class neoruntime_ipc_sdk.device.AfMeasurement(focus_energy, mean_luma, frame_id)[source]
Bases:
objectPer-window focus telemetry from the last AF measurement.
- focus_energy: list
- mean_luma: list
- frame_id: int
- __init__(focus_energy, mean_luma, frame_id)
- class neoruntime_ipc_sdk.device.DeviceClient(endpoint=None)[source]
Bases:
GrpcClientDevice Control Client
- Usage:
dev = DeviceClient()
dev.set_white_light(80) dev.set_ir_led(True) dev.set_ircut(IrCutMode.NIGHT)
dev.pan_left(speed=50) dev.call_preset(3)
dev.zoom_in() dev.focus_auto()
- set_white_light(level)[source]
- set_ir_led(on)[source]
- set_ircut(mode)[source]
- pan_left(speed=50)[source]
- pan_right(speed=50)[source]
- pan_stop()[source]
- tilt_up(speed=50)[source]
- tilt_down(speed=50)[source]
- tilt_stop()[source]
- ptz_stop()[source]
- save_preset(preset_id)[source]
- call_preset(preset_id)[source]
- zoom_in(speed=50)[source]
- zoom_out(speed=50)[source]
- zoom_stop()[source]
- zoom(speed)[source]
- set_zoom_level(level)[source]
- focus_in(speed=50)[source]
- focus_out(speed=50)[source]
- focus_stop()[source]
- focus(speed)[source]
- focus_auto(enable=True)[source]
- set_focus_level(level)[source]
- get_lens_status()[source]
- set_lens_limits(zoom_limit=None, focus_limit=None)[source]
Set lens axis position limits.
- Parameters:
Example:
dev.set_lens_limits(zoom_limit={"min_pos": 0, "max_pos": 1000}) dev.set_lens_limits( zoom_limit={"min_pos": 0, "max_pos": 1000}, focus_limit={"min_pos": 0, "max_pos": 800}, )
- oneshot_autofocus(timeout=20.0)[source]
Perform a single autofocus cycle: enable → wait for convergence → disable.
This is a composite operation that: 1. Enables continuous autofocus 2. Polls lens status until focus motor settles (or timeout) 3. Disables continuous autofocus
- Parameters:
timeout (float) – Maximum seconds to wait for focus convergence (default: 20.0)
- Raises:
RuntimeError – If autofocus fails to converge within timeout
TimeoutError – If focus motor does not settle within timeout
- start_oneshot_af()[source]
Start a one-shot autofocus job and return its handle immediately.
Unlike
oneshot_autofocus()(a blocking composite over the legacy SetAutofocus RPC), this returns at once; pair it withget_autofocus_status()to poll for convergence.
- start_zoom_follow(ratio)[source]
Start continuous autofocus locked to a zoom ratio.
- Parameters:
ratio (float) – Zoom ratio the focus engine should track (e.g. 1.5).
- get_autofocus_status()[source]
Snapshot of the autofocus engine (job, progress, lens positions).
- cancel_autofocus(job_id=0)[source]
Cancel an autofocus job.
- Parameters:
job_id (int) – Job to cancel; 0 (default) cancels the active job.
- set_af_windows(enabled, windows, stream_id='main')[source]
Set autofocus measurement windows for a stream.
- get_af_measurement()[source]
Latest per-window focus telemetry (focus energy / luma).
- set_wiegand_out(channel, enable)[source]
Enable or disable a Wiegand output channel.
- get_wiegand_out(channel)[source]
Get the enabled state of a Wiegand output channel.
- rs485_init(baudrate, config='')[source]
Initialize RS-485 serial interface.
- rs485_deinit()[source]
Deinitialize RS-485 serial interface.
- lens_reset_zero(zoom=True, focus=True)[source]
- control_iris(open)[source]
- set_iris_target(target)[source]
- lens_init()[source]
- lens_goto_ratio_distance(zoom_ratio, focus_distance_m)[source]
- gpio_set(pin, value)[source]
- gpio_get(pin)[source]
- get_device_status()[source]
- subscribe_events()[source]
DeviceClient
- class neoruntime_ipc_sdk.DeviceClient(endpoint=None)[source]
Bases:
GrpcClientDevice Control Client
- Usage:
dev = DeviceClient()
dev.set_white_light(80) dev.set_ir_led(True) dev.set_ircut(IrCutMode.NIGHT)
dev.pan_left(speed=50) dev.call_preset(3)
dev.zoom_in() dev.focus_auto()
- set_white_light(level)[source]
- set_ir_led(on)[source]
- set_ircut(mode)[source]
- pan_left(speed=50)[source]
- pan_right(speed=50)[source]
- pan_stop()[source]
- tilt_up(speed=50)[source]
- tilt_down(speed=50)[source]
- tilt_stop()[source]
- ptz_stop()[source]
- save_preset(preset_id)[source]
- call_preset(preset_id)[source]
- zoom_in(speed=50)[source]
- zoom_out(speed=50)[source]
- zoom_stop()[source]
- zoom(speed)[source]
- set_zoom_level(level)[source]
- focus_in(speed=50)[source]
- focus_out(speed=50)[source]
- focus_stop()[source]
- focus(speed)[source]
- focus_auto(enable=True)[source]
- set_focus_level(level)[source]
- get_lens_status()[source]
- set_lens_limits(zoom_limit=None, focus_limit=None)[source]
Set lens axis position limits.
- Parameters:
Example:
dev.set_lens_limits(zoom_limit={"min_pos": 0, "max_pos": 1000}) dev.set_lens_limits( zoom_limit={"min_pos": 0, "max_pos": 1000}, focus_limit={"min_pos": 0, "max_pos": 800}, )
- oneshot_autofocus(timeout=20.0)[source]
Perform a single autofocus cycle: enable → wait for convergence → disable.
This is a composite operation that: 1. Enables continuous autofocus 2. Polls lens status until focus motor settles (or timeout) 3. Disables continuous autofocus
- Parameters:
timeout (float) – Maximum seconds to wait for focus convergence (default: 20.0)
- Raises:
RuntimeError – If autofocus fails to converge within timeout
TimeoutError – If focus motor does not settle within timeout
- start_oneshot_af()[source]
Start a one-shot autofocus job and return its handle immediately.
Unlike
oneshot_autofocus()(a blocking composite over the legacy SetAutofocus RPC), this returns at once; pair it withget_autofocus_status()to poll for convergence.
- start_zoom_follow(ratio)[source]
Start continuous autofocus locked to a zoom ratio.
- Parameters:
ratio (float) – Zoom ratio the focus engine should track (e.g. 1.5).
- get_autofocus_status()[source]
Snapshot of the autofocus engine (job, progress, lens positions).
- cancel_autofocus(job_id=0)[source]
Cancel an autofocus job.
- Parameters:
job_id (int) – Job to cancel; 0 (default) cancels the active job.
- set_af_windows(enabled, windows, stream_id='main')[source]
Set autofocus measurement windows for a stream.
- get_af_measurement()[source]
Latest per-window focus telemetry (focus energy / luma).
- set_wiegand_out(channel, enable)[source]
Enable or disable a Wiegand output channel.
- get_wiegand_out(channel)[source]
Get the enabled state of a Wiegand output channel.
- rs485_init(baudrate, config='')[source]
Initialize RS-485 serial interface.
- rs485_deinit()[source]
Deinitialize RS-485 serial interface.
- lens_reset_zero(zoom=True, focus=True)[source]
- control_iris(open)[source]
- set_iris_target(target)[source]
- lens_init()[source]
- lens_goto_ratio_distance(zoom_ratio, focus_distance_m)[source]
- gpio_set(pin, value)[source]
- gpio_get(pin)[source]
- get_device_status()[source]
- subscribe_events()[source]
数据类型
DeviceStatus
- class neoruntime_ipc_sdk.DeviceStatus(soc_temp_c: 'float', mcu_temp_c: 'float', light_sensor: 'int', ptz_pan_pos: 'int', ptz_tilt_pos: 'int', zoom_pos: 'int', focus_pos: 'int', autofocus_enabled: 'bool', ircut_mode: 'IrCutMode', white_light_level: 'int', ir_led_on: 'bool', mcu_version: 'str', mcu_uptime_ms: 'int')[source]
- __init__(soc_temp_c, mcu_temp_c, light_sensor, ptz_pan_pos, ptz_tilt_pos, zoom_pos, focus_pos, autofocus_enabled, ircut_mode, white_light_level, ir_led_on, mcu_version, mcu_uptime_ms)
DeviceEvent
- class neoruntime_ipc_sdk.DeviceEvent(type: 'EventType', timestamp_ns: 'int', gpio_pin: 'int' = 0, gpio_value: 'bool' = False, light_sensor_value: 'int' = 0, temperature: 'float' = 0.0)[source]
- class EventType(value)[source]
- GPIO_CHANGE = 0
- LIGHT_SENSOR_CHANGE = 1
- TEMPERATURE_ALERT = 2
- PTZ_MOVE_COMPLETE = 3
- FOCUS_COMPLETE = 4
- __init__(type, timestamp_ns, gpio_pin=0, gpio_value=False, light_sensor_value=0, temperature=0.0)
IrCutMode
使用示例
灯光控制
from neoruntime_ipc_sdk import DeviceClient, IrCutMode
dev = DeviceClient()
# 白光灯控制
dev.set_white_light(0) # 关闭
dev.set_white_light(50) # 50% 亮度
dev.set_white_light(100) # 100% 亮度
# 红外灯控制
dev.set_ir_led(True) # 打开
dev.set_ir_led(False) # 关闭
# 红外滤光片控制
dev.set_ircut(IrCutMode.DAY) # 日间模式(滤光片开启)
dev.set_ircut(IrCutMode.NIGHT) # 夜间模式(滤光片关闭)
dev.set_ircut(IrCutMode.AUTO) # 自动模式
云台控制 (PTZ)
# 左右移动
dev.pan_left(speed=50) # 向左移动
dev.pan_right(speed=50) # 向右移动
dev.pan_stop() # 停止水平移动
# 上下移动
dev.tilt_up(speed=50) # 向上移动
dev.tilt_down(speed=50) # 向下移动
dev.tilt_stop() # 停止垂直移动
# 停止所有云台运动
dev.ptz_stop()
预置位控制
# 保存预置位
dev.save_preset(1) # 保存当前位置到预置位 1
# 调用预置位
dev.call_preset(1) # 移动到预置位 1
镜头控制
# 镜头初始化
dev.lens_init() # 初始化镜头模组
# 变焦
dev.zoom_in(speed=50) # 放大
dev.zoom_out(speed=50) # 缩小
dev.zoom_stop() # 停止变焦
# 设置变焦级别 (0.0 ~ 1.0)
dev.set_zoom_level(0.5) # 50% 变焦位置
# 对焦
dev.focus_in(speed=50) # 远焦
dev.focus_out(speed=50) # 近焦
dev.focus_stop() # 停止对焦
# 设置对焦级别 (0.0 ~ 1.0)
dev.set_focus_level(0.5) # 50% 对焦位置
# 自动对焦
dev.focus_auto(enable=True) # 开启自动对焦
dev.focus_auto(enable=False) # 关闭自动对焦
# 单次自动对焦(复合操作:开启→等待收敛→关闭)
dev.oneshot_autofocus(timeout=20.0)
# 变焦+对焦联动 (按光学变焦比和对焦距离)
dev.lens_goto_ratio_distance(zoom_ratio=2.0, focus_distance_m=3.0)
# 光圈控制
dev.control_iris(open=True) # 打开光圈
dev.set_iris_target(128) # 设置光圈目标值
# 镜头归零
dev.lens_reset_zero(zoom=True, focus=True) # 双轴归零
# 设置镜头限位
dev.set_lens_limits(zoom_limit={"min_pos": 0, "max_pos": 1000})
dev.set_lens_limits(
zoom_limit={"min_pos": 0, "max_pos": 1000},
focus_limit={"min_pos": 0, "max_pos": 800},
)
# 获取镜头状态
status = dev.get_lens_status()
print(f"变焦位置: {status['zoom_pos']}")
print(f"对焦位置: {status['focus_pos']}")
print(f"变焦状态: {status['zoom_state']}") # 0=未就绪, 1=空闲, 2=运行中
print(f"自动对焦: {status['autofocus_enabled']}")
GPIO 控制
# 读取 GPIO
value = dev.gpio_get(12)
print(f"GPIO 12 状态: {'高' if value else '低'}")
# 写入 GPIO
dev.gpio_set(21, True) # 设置为高电平
dev.gpio_set(21, False) # 设置为低电平
# 控制继电器
dev.gpio_set(22, True) # 打开继电器
韦根 (Wiegand) 控制
# 设置韦根输出
dev.set_wiegand_out(channel=0, enable=True) # 启用韦根通道 0
dev.set_wiegand_out(channel=1, enable=False) # 禁用韦根通道 1
# 查询韦根输出状态
enabled = dev.get_wiegand_out(channel=0)
print(f"韦根通道 0: {'启用' if enabled else '禁用'}")
RS-485 串口控制
# 初始化 RS-485
dev.rs485_init(baudrate=9600)
# 发送数据
dev.rs485_tx(b"hello")
# 反初始化
dev.rs485_deinit()
获取设备状态
# 获取完整状态
status = dev.get_device_status()
print(f"SoC 温度: {status.soc_temp_c}°C")
print(f"MCU 温度: {status.mcu_temp_c}°C")
print(f"光照传感器: {status.light_sensor}")
print(f"白光灯: {status.white_light_level}%")
print(f"红外灯: {'开' if status.ir_led_on else '关'}")
print(f"IR-Cut: {status.ircut_mode}")
print(f"云台位置: Pan={status.ptz_pan_pos}, Tilt={status.ptz_tilt_pos}")
print(f"变焦位置: {status.zoom_pos}")
print(f"对焦位置: {status.focus_pos}")
print(f"自动对焦: {'启用' if status.autofocus_enabled else '禁用'}")
print(f"MCU 版本: {status.mcu_version}")
print(f"MCU 运行时间: {status.mcu_uptime_ms}ms")
监控设备事件
# 订阅设备事件
for event in dev.subscribe_events():
print(f"事件类型: {event.type}")
print(f"时间戳: {event.timestamp_ns}")
if event.type == DeviceEvent.EventType.GPIO_CHANGE:
print(f"GPIO 引脚: {event.gpio_pin}, 值: {event.gpio_value}")
elif event.type == DeviceEvent.EventType.LIGHT_SENSOR_CHANGE:
print(f"光照传感器值: {event.light_sensor_value}")
elif event.type == DeviceEvent.EventType.TEMPERATURE_ALERT:
print(f"温度告警: {event.temperature}°C")
elif event.type == DeviceEvent.EventType.PTZ_MOVE_COMPLETE:
print("PTZ 移动完成")
elif event.type == DeviceEvent.EventType.FOCUS_COMPLETE:
print("对焦完成")
上下文管理器
# 使用上下文管理器自动管理连接
with DeviceClient() as dev:
dev.set_white_light(80)
status = dev.get_device_status()
print(f"灯光: {status.white_light_level}%")
错误处理
try:
dev.set_white_light(150) # 无效的值
except RuntimeError as e:
print(f"设置失败: {e}")
try:
value = dev.gpio_get(99) # 无效引脚
except RuntimeError as e:
print(f"GPIO 读取失败: {e}")