相机控制 API

Camera Control Client

Comprehensive camera pipeline control: ISP, encoder, RTSP, OSD, stream management, profiles, capabilities, and hardware status.

neoruntime_ipc_sdk.camera.pip_dest(frame_w, frame_h, inset_w, inset_h, corner='bottom-right', margin=16)[source]

Position a picture-in-picture inset for mode="overlay" pushes.

Returns (dest_x, dest_y) placing a inset_w``×``inset_h inset inside a frame_w``×``frame_h stream frame, margin pixels from the chosen corner (one of "top-left" / "top-right" / "bottom-left" / "bottom-right"). Coordinates are rounded down to even values — NV12 chroma is 2×2 subsampled, so an odd offset would misalign the inset’s color plane against its luma.

Raises ValueError for an unknown corner, non-positive inset dims, negative margin, or an inset that does not fit with its margin. Typical use:

x, y = pip_dest(1920, 1080, 480, 270, "bottom-right", 32)
cam.push_frame(bid, 480, 270, stride, mode="overlay",
               stream_id="main", dest_x=x, dest_y=y)
class neoruntime_ipc_sdk.camera.CameraClient(endpoint=None)[source]

Bases: GrpcClient

Camera pipeline control client.

Usage:

cam = CameraClient()

# ISP
cam.set_isp(brightness=60, contrast=50)
isp = cam.get_isp()

# Encoder
cam.set_encoder("main", bitrate_bps=8_000_000)

# RTSP
cam.set_rtsp_enabled(True)

# Streams
streams = cam.get_stream_status()
cam.add_stream("third", 1920, 1080, 30, "h264", 4_000_000, 30)

# Profiles
cam.switch_profile("night")
cam.backup_profile()

# Capabilities
caps = cam.get_capabilities()
set_isp(config=None, **kwargs)[source]

Update ISP image pipeline settings.

get_isp()[source]

Get current ISP configuration.

get_transform()[source]
set_transform(cfg)[source]
set_encoder(stream_name='main', bitrate_bps=0, framerate=0, gop=0)[source]

Dynamic encoder config (no restart).

reconfigure_encoder(stream_name, width=0, height=0, codec='', bitrate_bps=0, fps=0, gop=0)[source]

Full encoder reconfiguration (brief restart, ~100ms).

set_rtsp_enabled(enabled)[source]
set_osd(streams)[source]

Update OSD text and datetime overlays per stream.

Parameters:

streams (list[dict]) – list of dicts with keys: stream_name, text_overlays (list of dicts), datetime_overlays (list of dicts)

set_ai_overlay(enabled, show_label=True, show_confidence=True, line_thickness=2)[source]
set_imaging_mode(mode)[source]

Switch day/night imaging mode.

Parameters:

mode (str) – “day”, “infrared” or “auto” (light-sensor driven).

Returns: the resulting InfraredStatus.

get_infrared_status()[source]

Current day/night imaging state (mode, PWMs, light sensor).

set_infrared_settings(auto_follow=None, near_pwm=None, far_pwm=None, night_enter=None, day_enter=None)[source]

Update IR light settings; omitted fields (None) are left unchanged.

Parameters:
  • auto_follow (bool | None) – tie IR output to optical zoom ratio.

  • far_pwm (near_pwm /) – manual IR intensities (0-100).

  • day_enter (night_enter /) – light-sensor thresholds for auto mode.

clear_infrared_manual()[source]

Drop manual IR overrides and return to profile-driven output.

list_ir_presets()[source]

Saved IR-light profiles (per zoom ratio).

save_ir_preset(name, zoom_ratio, near_pwm, far_pwm)[source]

Save (or overwrite) an IR preset and return the new list.

delete_ir_preset(name)[source]

Delete an IR preset by name and return the remaining list.

get_privacy_mask()[source]

Current static + dynamic (AI) privacy-mask configuration.

set_privacy_mask(settings=None, *, color=None, blur_radius=None, enabled=None, regions=None, dpm_enabled=None, dpm_labels=None, dpm_mode=None, dpm_color=None)[source]

Update privacy-mask configuration with merge semantics.

Only the fields given as arguments are changed; everything else (including existing regions) is read back from the device and preserved, so partial updates never wipe masks.

Parameters:
  • settings (PrivacyMaskSettings | None) – full PrivacyMaskSettings to apply wholesale (optional).

  • color (int | None) – 0x00RRGGBB fill color (used when blur_radius=0).

  • blur_radius (int | None) – pixelation block size 2-64; 0 = solid color.

  • enabled (bool | None) – global static-mask on/off.

  • regions (list[dict] | None) – list of {id, name, enabled, points_x, points_y} with normalized polygon coordinates (up to 8 points).

  • dpm_* – dynamic (AI) privacy-mask options.

get_osd()[source]

Read back OSD overlay config, shaped like set_osd() input.

Returns: list of {stream_name, text_overlays, datetime_overlays, image_overlays}; each overlay is a plain dict of its proto fields, so the result can be edited and fed straight back into set_osd().

get_config_field(field_path)[source]

Read one camera-daemon config field by dotted path.

Parameters:

field_path (str) – e.g. “frontend.hailort.use-hailort-service”.

Returns: the current value encoded as a string.

set_config_field(field_path, value)[source]

Write one camera-daemon config field by dotted path.

Parameters:
  • field_path (str) – dotted config path.

  • value – value encoded as a string (e.g. “true”, “42”, “1.5”); non-str values are converted with str().

get_stream_status(timeout_s=None)[source]

List live streams with encoder state; timeout_s bounds the RPC (None waits indefinitely, gRPC’s default).

push_frame(buffer_id, width, height, stride, mode='replace', pts_ns=0, dest_x=0, dest_y=0, stream_id='', end_of_stream=False, session_id='', timeout_s=None)[source]

Push one frame into the daemon’s encoder feed (PushFrame).

buffer_id must be a DSP-registry buffer id (see DspBufferPool.buffer_id / DspClient.import_frame()) — a raw fd number never crosses gRPC. The registered buffer’s geometry must equal width/height.

Modes (P2):

  • "replace" — full-frame NV12 content copy over one stream’s encode output. stream_id empty keeps the P0 semantics (any stream whose encode dims match); an explicit stream_id targets that stream and requires dims equal to its encode resolution.

  • "overlay" — compose on top of the live stream. Requires stream_id. dest_x/dest_y (even, NV12 chroma alignment) position the inset. NV12 insets paste opaquely; ARGB32 insets alpha-blend on the CPU.

pts_ns paces the bake (device CLOCK_MONOTONIC domain, same clock as frame timestamps): 0 = due immediately; a future value holds the frame until the encoder frontier passes it, and a newer due frame supersedes (drops) older due frames for the same target. end_of_stream=True (buffer_id 0) flushes the session and restores the ISP path at the next IDR.

session_id tags the injection session (P2-13 lifecycle): correlation and observability only — the daemon anchors the session on the buffer owner’s UDS connection and closes it on that client’s disconnect regardless of the tag.

push_frame_stream(frames, timeout_s=None)[source]

Push a run of frames over one client-streaming RPC (PushFrameStream).

frames is an iterable (or generator) of keyword dicts, each accepted by push_frame() — e.g. {"buffer_id": bid, "width": w, "height": h, "stride": s, "mode": "overlay", "stream_id": "main", "dest_x": 64, "dest_y": 64}. A dict with end_of_stream=True closes the injection session server-side before the RPC returns; omitting any EOS dict ends the stream with a clean half-close that LEAVES the session open (close later via stop_injection()).

Per-request semantics are identical to unary push_frame(); the first server-side rejection ends the stream and is re-raised here as RuntimeError (the accepted-frame count at that point rides the exception text). A session_id key in any request dict tags the session (P2-13) — the daemon records the latest non-empty tag and echoes it on the response.

Returns an InjectionResult whose accepted_frame_count reports how many frames the daemon accepted before the stream ended.

injection_status(timeout_s=None)[source]

Injection session snapshot: active, mode, counters, queue depth, the live session’s lifecycle tag (empty when untagged/closed), and the write-lease set (in_flight_buffer_ids + reports_in_flight_buffers; Fix-1).

stop_injection(timeout_s=None)[source]

Close the injection session and restore the ISP path (next IDR).

add_stream(stream_id, width, height, fps, codec='h264', bitrate=4000000, gop=30)[source]
remove_stream(stream_name)[source]
reconfigure_pipeline(streams)[source]
get_profile()[source]
list_profiles()[source]

Returns (profile_names, current_profile).

switch_profile(name)[source]
backup_profile(path='')[source]
get_sensor_info(sensor_index=0)[source]
get_capabilities()[source]
get_hardware_status()[source]
set_led_duty(led_id, duty_percent)[source]
get_led_duty(led_id)[source]
set_ircut(mode)[source]

Set IR-cut filter. mode: 0=day, 1=night. Returns current mode.

get_ircut()[source]
mcu_raw_request(cmd, payload=b'')[source]
set_fan(enable)[source]
get_fan()[source]
set_heat(enable)[source]
get_heat()[source]
set_radar(enable)[source]
get_radar()[source]
set_alarm_out(channel, enable)[source]
get_alarm_out(channel)[source]
get_alarm_outputs()[source]
rs485_init(baudrate=9600, config='8N1')[source]
rs485_deinit()[source]
rs485_tx(data)[source]

CameraClient

class neoruntime_ipc_sdk.CameraClient(endpoint=None)[source]

Bases: GrpcClient

Camera pipeline control client.

Usage:

cam = CameraClient()

# ISP
cam.set_isp(brightness=60, contrast=50)
isp = cam.get_isp()

# Encoder
cam.set_encoder("main", bitrate_bps=8_000_000)

# RTSP
cam.set_rtsp_enabled(True)

# Streams
streams = cam.get_stream_status()
cam.add_stream("third", 1920, 1080, 30, "h264", 4_000_000, 30)

# Profiles
cam.switch_profile("night")
cam.backup_profile()

# Capabilities
caps = cam.get_capabilities()
set_isp(config=None, **kwargs)[source]

Update ISP image pipeline settings.

get_isp()[source]

Get current ISP configuration.

get_transform()[source]
set_transform(cfg)[source]
set_encoder(stream_name='main', bitrate_bps=0, framerate=0, gop=0)[source]

Dynamic encoder config (no restart).

reconfigure_encoder(stream_name, width=0, height=0, codec='', bitrate_bps=0, fps=0, gop=0)[source]

Full encoder reconfiguration (brief restart, ~100ms).

set_rtsp_enabled(enabled)[source]
set_osd(streams)[source]

Update OSD text and datetime overlays per stream.

Parameters:

streams (list[dict]) – list of dicts with keys: stream_name, text_overlays (list of dicts), datetime_overlays (list of dicts)

set_ai_overlay(enabled, show_label=True, show_confidence=True, line_thickness=2)[source]
set_imaging_mode(mode)[source]

Switch day/night imaging mode.

Parameters:

mode (str) – “day”, “infrared” or “auto” (light-sensor driven).

Returns: the resulting InfraredStatus.

get_infrared_status()[source]

Current day/night imaging state (mode, PWMs, light sensor).

set_infrared_settings(auto_follow=None, near_pwm=None, far_pwm=None, night_enter=None, day_enter=None)[source]

Update IR light settings; omitted fields (None) are left unchanged.

Parameters:
  • auto_follow (bool | None) – tie IR output to optical zoom ratio.

  • far_pwm (near_pwm /) – manual IR intensities (0-100).

  • day_enter (night_enter /) – light-sensor thresholds for auto mode.

clear_infrared_manual()[source]

Drop manual IR overrides and return to profile-driven output.

list_ir_presets()[source]

Saved IR-light profiles (per zoom ratio).

save_ir_preset(name, zoom_ratio, near_pwm, far_pwm)[source]

Save (or overwrite) an IR preset and return the new list.

delete_ir_preset(name)[source]

Delete an IR preset by name and return the remaining list.

get_privacy_mask()[source]

Current static + dynamic (AI) privacy-mask configuration.

set_privacy_mask(settings=None, *, color=None, blur_radius=None, enabled=None, regions=None, dpm_enabled=None, dpm_labels=None, dpm_mode=None, dpm_color=None)[source]

Update privacy-mask configuration with merge semantics.

Only the fields given as arguments are changed; everything else (including existing regions) is read back from the device and preserved, so partial updates never wipe masks.

Parameters:
  • settings (PrivacyMaskSettings | None) – full PrivacyMaskSettings to apply wholesale (optional).

  • color (int | None) – 0x00RRGGBB fill color (used when blur_radius=0).

  • blur_radius (int | None) – pixelation block size 2-64; 0 = solid color.

  • enabled (bool | None) – global static-mask on/off.

  • regions (list[dict] | None) – list of {id, name, enabled, points_x, points_y} with normalized polygon coordinates (up to 8 points).

  • dpm_* – dynamic (AI) privacy-mask options.

get_osd()[source]

Read back OSD overlay config, shaped like set_osd() input.

Returns: list of {stream_name, text_overlays, datetime_overlays, image_overlays}; each overlay is a plain dict of its proto fields, so the result can be edited and fed straight back into set_osd().

get_config_field(field_path)[source]

Read one camera-daemon config field by dotted path.

Parameters:

field_path (str) – e.g. “frontend.hailort.use-hailort-service”.

Returns: the current value encoded as a string.

set_config_field(field_path, value)[source]

Write one camera-daemon config field by dotted path.

Parameters:
  • field_path (str) – dotted config path.

  • value – value encoded as a string (e.g. “true”, “42”, “1.5”); non-str values are converted with str().

get_stream_status(timeout_s=None)[source]

List live streams with encoder state; timeout_s bounds the RPC (None waits indefinitely, gRPC’s default).

push_frame(buffer_id, width, height, stride, mode='replace', pts_ns=0, dest_x=0, dest_y=0, stream_id='', end_of_stream=False, session_id='', timeout_s=None)[source]

Push one frame into the daemon’s encoder feed (PushFrame).

buffer_id must be a DSP-registry buffer id (see DspBufferPool.buffer_id / DspClient.import_frame()) — a raw fd number never crosses gRPC. The registered buffer’s geometry must equal width/height.

Modes (P2):

  • "replace" — full-frame NV12 content copy over one stream’s encode output. stream_id empty keeps the P0 semantics (any stream whose encode dims match); an explicit stream_id targets that stream and requires dims equal to its encode resolution.

  • "overlay" — compose on top of the live stream. Requires stream_id. dest_x/dest_y (even, NV12 chroma alignment) position the inset. NV12 insets paste opaquely; ARGB32 insets alpha-blend on the CPU.

pts_ns paces the bake (device CLOCK_MONOTONIC domain, same clock as frame timestamps): 0 = due immediately; a future value holds the frame until the encoder frontier passes it, and a newer due frame supersedes (drops) older due frames for the same target. end_of_stream=True (buffer_id 0) flushes the session and restores the ISP path at the next IDR.

session_id tags the injection session (P2-13 lifecycle): correlation and observability only — the daemon anchors the session on the buffer owner’s UDS connection and closes it on that client’s disconnect regardless of the tag.

push_frame_stream(frames, timeout_s=None)[source]

Push a run of frames over one client-streaming RPC (PushFrameStream).

frames is an iterable (or generator) of keyword dicts, each accepted by push_frame() — e.g. {"buffer_id": bid, "width": w, "height": h, "stride": s, "mode": "overlay", "stream_id": "main", "dest_x": 64, "dest_y": 64}. A dict with end_of_stream=True closes the injection session server-side before the RPC returns; omitting any EOS dict ends the stream with a clean half-close that LEAVES the session open (close later via stop_injection()).

Per-request semantics are identical to unary push_frame(); the first server-side rejection ends the stream and is re-raised here as RuntimeError (the accepted-frame count at that point rides the exception text). A session_id key in any request dict tags the session (P2-13) — the daemon records the latest non-empty tag and echoes it on the response.

Returns an InjectionResult whose accepted_frame_count reports how many frames the daemon accepted before the stream ended.

injection_status(timeout_s=None)[source]

Injection session snapshot: active, mode, counters, queue depth, the live session’s lifecycle tag (empty when untagged/closed), and the write-lease set (in_flight_buffer_ids + reports_in_flight_buffers; Fix-1).

stop_injection(timeout_s=None)[source]

Close the injection session and restore the ISP path (next IDR).

add_stream(stream_id, width, height, fps, codec='h264', bitrate=4000000, gop=30)[source]
remove_stream(stream_name)[source]
reconfigure_pipeline(streams)[source]
get_profile()[source]
list_profiles()[source]

Returns (profile_names, current_profile).

switch_profile(name)[source]
backup_profile(path='')[source]
get_sensor_info(sensor_index=0)[source]
get_capabilities()[source]
get_hardware_status()[source]
set_led_duty(led_id, duty_percent)[source]
get_led_duty(led_id)[source]
set_ircut(mode)[source]

Set IR-cut filter. mode: 0=day, 1=night. Returns current mode.

get_ircut()[source]
mcu_raw_request(cmd, payload=b'')[source]
set_fan(enable)[source]
get_fan()[source]
set_heat(enable)[source]
get_heat()[source]
set_radar(enable)[source]
get_radar()[source]
set_alarm_out(channel, enable)[source]
get_alarm_out(channel)[source]
get_alarm_outputs()[source]
rs485_init(baudrate=9600, config='8N1')[source]
rs485_deinit()[source]
rs485_tx(data)[source]

数据类型

ISPConfig

class neoruntime_ipc_sdk.ISPConfig(brightness: 'int' = -1, contrast: 'int' = -1, saturation: 'int' = -1, sharpness: 'int' = -1, manual_mode: 'bool | None' = None, auto_exposure: 'bool | None' = None, backlight: 'int' = -1, exposure_time_us: 'int' = -1, gain: 'int' = -1, noise_reduction: 'int' = -1, wdr_value: 'int' = -1, powerline_freq: 'int' = -1, awb_index: 'int' = -1)[source]
brightness: int = -1
contrast: int = -1
saturation: int = -1
sharpness: int = -1
manual_mode: bool | None = None
auto_exposure: bool | None = None
backlight: int = -1
exposure_time_us: int = -1
gain: int = -1
noise_reduction: int = -1
wdr_value: int = -1
powerline_freq: int = -1
awb_index: int = -1
__init__(brightness=-1, contrast=-1, saturation=-1, sharpness=-1, manual_mode=None, auto_exposure=None, backlight=-1, exposure_time_us=-1, gain=-1, noise_reduction=-1, wdr_value=-1, powerline_freq=-1, awb_index=-1)

TransformConfig

class neoruntime_ipc_sdk.TransformConfig(rotation: 'int' = 0, flip: 'int' = 0, dewarp: 'bool' = False, grayscale: 'bool' = False)[source]
rotation: int = 0
flip: int = 0
dewarp: bool = False
grayscale: bool = False
__init__(rotation=0, flip=0, dewarp=False, grayscale=False)

Capabilities

class neoruntime_ipc_sdk.Capabilities(has_video: 'bool' = False, has_codec: 'bool' = False, has_led: 'bool' = False, has_sensor: 'bool' = False, has_mcu: 'bool' = False, has_env_ctrl: 'bool' = False, has_alarm: 'bool' = False, has_rs485: 'bool' = False, has_osd: 'bool' = False, has_draw: 'bool' = False, has_audio: 'bool' = False)[source]
has_video: bool = False
has_codec: bool = False
has_led: bool = False
has_sensor: bool = False
has_mcu: bool = False
has_env_ctrl: bool = False
has_alarm: bool = False
has_rs485: bool = False
has_osd: bool = False
has_draw: bool = False
has_audio: bool = False
__init__(has_video=False, has_codec=False, has_led=False, has_sensor=False, has_mcu=False, has_env_ctrl=False, has_alarm=False, has_rs485=False, has_osd=False, has_draw=False, has_audio=False)

SensorInfo

class neoruntime_ipc_sdk.SensorInfo(available: 'bool', sensor_model: 'str', i2c_bus: 'int', i2c_address: 'str', pixel_format: 'int')[source]
available: bool
sensor_model: str
i2c_bus: int
i2c_address: str
pixel_format: int
__init__(available, sensor_model, i2c_bus, i2c_address, pixel_format)

StreamStatus

class neoruntime_ipc_sdk.StreamStatus(stream_id, status, has_encoder, codec, width, height, fps, bitrate_bps, gop, packets_published=0, queue_overflow_drops=0, client_send_drops=0, client_send_failures=0, client_disconnects=0, last_packet_seq=0, publisher_clients=0, bake_skips=0, strict_locked=0, strict_degraded=0, strict_skips=0, stream_epoch=0, overlay_layer_count=0, overlay_late_commands=0, overlay_epoch_rejects=0, overlay_no_binding_drops=0)[source]

One display stream from CameraClient.get_stream_status().

Fields come in four groups, in declaration order — identity & encode geometry (stream_id..``gop``); encoded-stream fan-out observability (packets_published..``publisher_clients``); overlay bake / strict frame-lock counters (bake_skips..``strict_skips``); behavior decoupling & frame-sync state (stream_epoch..``overlay_no_binding_drops``). Per-field semantics in the inline comments of each group.

stream_id: str
status: str
has_encoder: bool
codec: str
width: int
height: int
fps: int
bitrate_bps: int
gop: int
packets_published: int = 0
queue_overflow_drops: int = 0
client_send_drops: int = 0
client_send_failures: int = 0
client_disconnects: int = 0
last_packet_seq: int = 0
publisher_clients: int = 0
bake_skips: int = 0
strict_locked: int = 0
strict_degraded: int = 0
strict_skips: int = 0
stream_epoch: int = 0
overlay_layer_count: int = 0
overlay_late_commands: int = 0
overlay_epoch_rejects: int = 0
overlay_no_binding_drops: int = 0
__init__(stream_id, status, has_encoder, codec, width, height, fps, bitrate_bps, gop, packets_published=0, queue_overflow_drops=0, client_send_drops=0, client_send_failures=0, client_disconnects=0, last_packet_seq=0, publisher_clients=0, bake_skips=0, strict_locked=0, strict_degraded=0, strict_skips=0, stream_epoch=0, overlay_layer_count=0, overlay_late_commands=0, overlay_epoch_rejects=0, overlay_no_binding_drops=0)

HardwareStatus

class neoruntime_ipc_sdk.HardwareStatus(light_sensor_mv: 'int', light_sensor_lux: 'int', mcu_temp_millic: 'int', ain_mv: 'int', mcu_version: 'str', white_light_duty: 'int', ir_led_duty: 'int', ircut_mode: 'int')[source]
light_sensor_mv: int
light_sensor_lux: int
mcu_temp_millic: int
ain_mv: int
mcu_version: str
white_light_duty: int
ir_led_duty: int
ircut_mode: int
__init__(light_sensor_mv, light_sensor_lux, mcu_temp_millic, ain_mv, mcu_version, white_light_duty, ir_led_duty, ircut_mode)

EnvStatus

class neoruntime_ipc_sdk.EnvStatus(enabled: 'bool')[source]
enabled: bool
__init__(enabled)

PipelineStreamConfig

class neoruntime_ipc_sdk.PipelineStreamConfig(stream_id: 'str', input_width: 'int' = 0, input_height: 'int' = 0, input_framerate: 'int' = 0, codec: 'str' = 'h264', encoder_width: 'int' = 0, encoder_height: 'int' = 0, encoder_framerate: 'int' = 0, encoder_bitrate: 'int' = 0, encoder_gop: 'int' = 0)[source]
stream_id: str
input_width: int = 0
input_height: int = 0
input_framerate: int = 0
codec: str = 'h264'
encoder_width: int = 0
encoder_height: int = 0
encoder_framerate: int = 0
encoder_bitrate: int = 0
encoder_gop: int = 0
__init__(stream_id, input_width=0, input_height=0, input_framerate=0, codec='h264', encoder_width=0, encoder_height=0, encoder_framerate=0, encoder_bitrate=0, encoder_gop=0)

EncoderReconfigResult

class neoruntime_ipc_sdk.EncoderReconfigResult(success: 'bool', message: 'str', interrupt_ms: 'int' = 0)[source]
success: bool
message: str
interrupt_ms: int = 0
__init__(success, message, interrupt_ms=0)

InfraredStatus

class neoruntime_ipc_sdk.InfraredStatus(mode, transition, output_source, auto_follow, follow_active, manual_override, degraded, requested_near_pwm, requested_far_pwm, applied_near_pwm, applied_far_pwm, zoom_ratio, active_profile, selected_mode, light_percent, light_mv, light_milli, light_valid, night_enter, day_enter)[source]

Day/night imaging state reported by the camera pipeline.

mode: str
transition: str
output_source: str
auto_follow: bool
follow_active: bool
manual_override: bool
degraded: bool
requested_near_pwm: int
requested_far_pwm: int
applied_near_pwm: int
applied_far_pwm: int
zoom_ratio: float
active_profile: str
selected_mode: str
light_percent: int
light_mv: int
light_milli: int
light_valid: bool
night_enter: int
day_enter: int
__init__(mode, transition, output_source, auto_follow, follow_active, manual_override, degraded, requested_near_pwm, requested_far_pwm, applied_near_pwm, applied_far_pwm, zoom_ratio, active_profile, selected_mode, light_percent, light_mv, light_milli, light_valid, night_enter, day_enter)

IrPreset

class neoruntime_ipc_sdk.IrPreset(name, zoom_ratio, near_pwm, far_pwm)[source]

Saved IR-light profile bound to a zoom ratio.

name: str
zoom_ratio: float
near_pwm: int
far_pwm: int
__init__(name, zoom_ratio, near_pwm, far_pwm)

PrivacyMaskSettings

class neoruntime_ipc_sdk.PrivacyMaskSettings(color, blur_radius, enabled, regions, dpm_enabled, dpm_labels, dpm_mode, dpm_color)[source]

Static and dynamic (AI) privacy-mask configuration.

regions is a list of dicts: {id, name, enabled, points_x, points_y} with normalized [0.0-1.0] polygon coordinates (up to 8 points).

color: int
blur_radius: int
enabled: bool
regions: list[dict]
dpm_enabled: bool
dpm_labels: str
dpm_mode: str
dpm_color: int
__init__(color, blur_radius, enabled, regions, dpm_enabled, dpm_labels, dpm_mode, dpm_color)

使用示例

ISP 图像调节

from neoruntime_ipc_sdk import CameraClient, ISPConfig

cam = CameraClient()

# 读取当前 ISP 配置
cfg = cam.get_isp()
print(f"亮度: {cfg.brightness}, 对比度: {cfg.contrast}")

# 仅修改关心的字段(-1 表示保持不变)
cam.set_isp(ISPConfig(brightness=60, saturation=50))

# 或使用关键字参数
cam.set_isp(brightness=60, sharpness=128)

图像变换(翻转 / 旋转 / 灰度)

from neoruntime_ipc_sdk import CameraClient, TransformConfig

cam = CameraClient()

# 水平翻转 + 180° 旋转 + 灰度输出
cam.set_transform(TransformConfig(rotation=180, flip=1, grayscale=True))

红外与夜视

from neoruntime_ipc_sdk import CameraClient

cam = CameraClient()

# 查看当前日夜成像状态
status = cam.get_infrared_status()
print(status)

# 切换成像模式("auto" / "day" / "night" 等,见 daemon 支持)
cam.set_imaging_mode("night")

# 手动微调红外灯亮度(PWM)
cam.set_infrared_settings(near_pwm=80, far_pwm=120)

# 按变焦倍率保存/调用 IR 预设
cam.save_ir_preset("zoom_2x", zoom_ratio=2.0, near_pwm=60, far_pwm=90)
presets = cam.list_ir_presets()
cam.delete_ir_preset("zoom_2x")

编码器与码流

from neoruntime_ipc_sdk import CameraClient, PipelineStreamConfig

cam = CameraClient()

# 查看码流状态
for s in cam.get_stream_status():
    print(f"{s.stream_id}: {s.width}x{s.height}@{s.fps} {s.codec}")

# 运行时调整单条码流码率(不重启管线)
cam.set_encoder("main", bitrate_bps=6_000_000, gop=60)

# 结构化重配(宽高/编码器变化,返回中断时长)
result = cam.reconfigure_encoder(
    "main", width=2560, height=1440, bitrate_bps=8_000_000,
)
print(f"success={result.success}, 中断 {result.interrupt_ms}ms")

# 增删码流
cam.add_stream("sub2", 704, 576, fps=15, codec="h265", bitrate=1_500_000)
cam.remove_stream("sub2")

隐私遮挡

from neoruntime_ipc_sdk import CameraClient

cam = CameraClient()

# 启用静态遮挡区域(归一化坐标 0-1)
cam.set_privacy_mask(
    enabled=True,
    color=0,
    blur_radius=21,
    regions=[
        {"id": 1, "x": 0.05, "y": 0.05, "w": 0.2, "h": 0.15},
        {"id": 2, "x": 0.7, "y": 0.7, "w": 0.25, "h": 0.2},
    ],
)

# 查询当前配置
print(cam.get_privacy_mask())

环境与外设

from neoruntime_ipc_sdk import CameraClient

cam = CameraClient()

# 光感/温度等硬件状态
hw = cam.get_hardware_status()
print(f"光照 {hw.light_sensor_lux} lux, MCU {hw.mcu_temp_millic/1000:.1f}°C")

# 风扇 / 加热 / 雷达
cam.set_fan(True)
cam.set_heat(False)
print(cam.get_radar())

# 报警输出
cam.set_alarm_out(0, True)
print(cam.get_alarm_outputs())

# RS485 透传
cam.rs485_init(baudrate=9600, config="8N1")
cam.rs485_tx(b"\x01\x02\x03")

能力查询

caps = cam.get_capabilities()
print(f"LED: {caps.has_led}, RS485: {caps.has_rs485}, 音频: {caps.has_audio}")

上下文管理器

with CameraClient() as cam:
    print(cam.get_sensor_info())