Skip to main content

Crate grafton_visca

Crate grafton_visca 

Source
Expand description

§grafton-visca

Rust library for VISCA over IP protocol to control PTZ cameras.

§What is VISCA?

VISCA (Video System Control Architecture) is a protocol developed by Sony for controlling Ptz cameras commonly used in robotics, broadcasting, video conferencing, and surveillance applications. This crate implements VISCA over IP, allowing you to control networked Ptz cameras from Rust applications.

§Features

  • Camera-first API Architecture: Connect and noun accessors across blocking and async modes
  • Type-Safe Camera Profiles: Compile-time validation with camera-specific profiles
  • Feature-Gated Methods: Choose blocking or async at compile time with zero runtime overhead
  • Multi-Runtime Support: Tokio and smol can coexist with priority-based selection
  • Complete Command Coverage: Full VISCA protocol support across all camera types
  • Profile-Aware Conversions: Automatic unit conversions based on camera model
  • Comprehensive Inquiry: Query camera state for all supported features
  • Transport Abstraction: TCP, UDP, Serial, and custom transport implementations
  • Configuration APIs: CameraConfig for standard transports and CameraBuilder for custom transports
  • Unified Error Handling: Consistent error mapping across all transport types
  • Configurable Timeouts: Per-category timeout configuration for different command types
  • Command Cancellation: Cancel specific commands or entire socket operations
  • Async Completion Tracking: Wait for camera movements to complete with await methods
  • Serialization Support: Optional serde/schemars integration for all value types

§1.0 API Shape

The primary API is camera-first:

  • Use camera::Connect for simple TCP, UDP, and serial connections.
  • Use camera::CameraConfig when a standard transport needs explicit timeout, retry, keepalive, camera ID, or serial settings.
  • Use accessor-style controls such as camera.power().on() and camera.pan_tilt().position() for normal operation.
  • Import generic control traits from the crate root, for example PowerControl and ZoomControl; camera implementation submodules are internal.
  • Use CameraBuilder only when you already own a custom transport and need to attach it to the camera runtime.
  • Use UnitInterval for normalized 0.0..=1.0 control values and CameraId for configured VISCA camera addresses.
  • Use command::ViscaCommand as the raw VISCA escape hatch for custom command encoding and behavior metadata, and command::ResponseParser for typed built-in or raw custom inquiry responses.

§Serialization Support

All public value types support optional serialization through feature-gated serde and schemars derives:

[dependencies]
grafton-visca = { version = "1", features = ["serde", "schemars"] }

With these features enabled, you can serialize/deserialize all value types directly:

use grafton_visca::types::{PanSpeed, ZoomPosition, SpeedLevel};

// Serialize to JSON
let speed = PanSpeed::new(12).unwrap();
let json = serde_json::to_string(&speed).unwrap();
assert_eq!(json, "12");

// Deserialize from JSON
let speed: PanSpeed = serde_json::from_str("15").unwrap();
assert_eq!(speed.value(), 15);

// Works with enums too
let level = SpeedLevel::Medium;
let json = serde_json::to_string(&level).unwrap();
assert_eq!(json, "\"medium\"");

§Configuration Types with Serialization

Camera configuration types also support serialization, making it easy to save and load camera setups from configuration files or APIs:

use grafton_visca::camera::TransportOptions;
use grafton_visca::camera::profiles::ProfileId;

// Serialize camera profile
let profile = ProfileId::PtzOpticsG2;
let json = serde_json::to_string(&profile).unwrap();
assert_eq!(json, "\"ptz-optics-g2\"");

// Serialize transport configuration
let transport = TransportOptions::Tcp {
    address: "192.168.0.110:5678".to_string(),
};
let json = serde_json::to_string(&transport).unwrap();
// Can be loaded from config files, environment variables, etc.

With schemars feature, you can also generate JSON schemas for API documentation:

use grafton_visca::types::PanSpeed;
use schemars::schema_for;

let schema = schema_for!(PanSpeed);
// Use schema for API documentation, validation, etc.

§Model-Aware Parameter Validation

The library provides comprehensive parameter validation at multiple levels, ensuring commands are correct before being sent to the camera:

§Type-Safe Parameters with Conservative Defaults

All parameter types provide conservative VISCA-compliant ranges by default:

use grafton_visca::types::{PanSpeed, ZoomPosition, ZoomSpeed};

// All range types expose MIN/MAX constants for validation
assert_eq!(PanSpeed::MIN.value(), 0);
assert_eq!(PanSpeed::MAX.value(), 24);

// Validated constructors provide clear error messages
let speed = PanSpeed::new(15)?;  // Valid: 0-24
match PanSpeed::new(30) {
    Err(e) => println!("{}", e), // "PanSpeed must be between 0 and 24"
    _ => {}
}

// Speed types work seamlessly with SpeedLevel enum
let zoom = ZoomSpeed::from(SpeedLevel::Fast); // Automatic conversion
assert_eq!(zoom.value(), 6); // Fast = 6 for zoom

§Profile-Based Compile-Time Safety

Camera profiles carry model-specific limits and capabilities at compile time:

use grafton_visca::{camera::Connect, profiles::PtzOpticsG2, units::Degrees, SpeedLevel};

let camera = Connect::open_tcp_blocking::<PtzOpticsG2>("192.168.0.110")?;
camera.pan_tilt().absolute(Degrees(45.0), Degrees(10.0), SpeedLevel::Medium)?;

§Compile-Time Capability Gating

Vendor-specific controls are exposed through the same accessor path and are only available when the selected profile supports them:

use grafton_visca::{camera::Connect, profiles::PtzOpticsG2};

let camera = Connect::open_tcp_blocking::<PtzOpticsG2>("192.168.0.110")?;
camera.focus().lock()?;
camera.focus().unlock()?;

This multi-layered approach ensures:

  • Early error detection at construction time
  • Conservative defaults for generic usage
  • Profile-specific precision through compile-time validation

§Quick Start

§Blocking Example

use grafton_visca::{
    camera::Connect,
    camera::profiles::PtzOpticsG2,
    Error,
};

fn main() -> Result<(), Error> {
    // Create camera using convenience Connect helper
    let camera = Connect::open_tcp_blocking::<PtzOpticsG2>("192.168.0.110")?;

    // Use accessor-style API
    camera.power().on()?;
    camera.zoom().tele()?;
    camera.pan_tilt().home()?;

    Ok(())
}

§Async Example with Multi-Runtime Support

use grafton_visca::{
    camera::Connect,
    camera::profiles::PtzOpticsG2,
    runtime::{Runtime, TokioRuntime},
    Error,
};

#[tokio::main]
async fn main() -> Result<(), Error> {
    // Create camera using Connect helper with runtime
    let runtime = TokioRuntime::from_current()?;
    let camera = Connect::open_tcp_async::<PtzOpticsG2, _>(
        "192.168.0.110",
        runtime
    ).await?;

    // Use accessor-style API with async
    camera.power().on().await?;
    camera.zoom().tele().await?;
    camera.pan_tilt().home().await?;

    // Wait for movements to complete
    camera.await_idle().await?;

    Ok(())
}

§Explicit Runtime Selection Example

// Multiple runtime features can coexist, but runtime selection is explicit.
[dependencies]
grafton-visca = { version = "1", features = ["runtime-tokio", "runtime-smol"] }

use grafton_visca::{
    Error,
    camera::{Connect, profiles::PtzOpticsG2},
    runtime::SmolRuntime,
};

fn main() -> Result<(), Error> {
    smol::block_on(async {
        let runtime = SmolRuntime::new();
        let camera = Connect::open_tcp_async::<PtzOpticsG2, _>(
            "192.168.0.110",
            runtime,
        )
            .await?;

        camera.power().on().await?;
        camera.zoom().tele().await?;

        Ok(())
    })
}

§Configured Connection Example

use grafton_visca::{
    Error,
    camera::{CameraConfig, profiles::PtzOpticsG2},
    runtime::SmolRuntime,
    transport::{TcpKeepaliveConfig, TransportConfig},
};
use std::time::Duration;

fn main() -> Result<(), Error> {
    smol::block_on(async {
        let config = CameraConfig::<PtzOpticsG2>::tcp("192.168.0.110")
            .transport_config(TransportConfig {
                tcp_keepalive: Some(TcpKeepaliveConfig::new(Duration::from_secs(30))),
                ..TransportConfig::default()
            });

        let camera = config.open_async(SmolRuntime::new()).await?;

        camera.power().on().await?;
        camera.pan_tilt().home().await?;
        camera.zoom().tele().await?;

        Ok(())
    })
}

§Camera Profiles

The library includes pre-defined profiles such as PtzOpticsG2, SonyFR7, and GenericVisca. Profiles are selected at construction time with Connect or CameraConfig and then drive compile-time capability checks for the accessor API.

§Compile-Time Type Safety

The camera profile controls which accessors are available at compile time:

use grafton_visca::prelude::blocking::*;

let sony = Connect::open_udp_blocking::<SonyFR7>("192.168.0.110")?;
sony.nd_filter().set_mode(NdFilterMode::Clear)?;

let g2 = Connect::open_tcp_blocking::<PtzOpticsG2>("192.168.0.111")?;
// g2.nd_filter().set_mode(NdFilterMode::Clear)?; // Compile error: G2 has no ND filter capability

Runtime discovery metadata is available for every profile through Capabilities::from_profile::<P>(). Typed optional vendor controls use separate support markers, so the public API exposes only documented support: SonyFR7 has typed ND filter and variable speed controls. Dyn-api callers can query the same permission model with Capabilities::supports_typed(...); overlapping metadata fields remain discovery facts, not typed permission checks. Built-in PTZOptics profiles are not marked for typed Motion Sync from the current model capability specs.

§Transport Implementation

The library provides transport traits that you can implement for any communication method:

use grafton_visca::{transport::BlockingTransport, command::CommandKind, Error};
use bytes::Bytes;
use std::time::Duration;

struct MyTransport {
    // Your transport state
}

impl BlockingTransport for MyTransport {
    fn send_with_kind(&mut self, data: &[u8], kind: CommandKind) -> Result<(), Error> {
        // Send data over your transport with proper framing based on kind
        Ok(())
    }

    fn recv(&mut self) -> Result<Bytes, Error> {
        // Receive response from your transport
        Ok(Bytes::new())
    }

    fn recv_with_timeout(&mut self, timeout: Duration) -> Result<Bytes, Error> {
        // Receive response with timeout
        Ok(Bytes::new())
    }
}

Example transport implementations are demonstrated in:

  • examples/quickstart.rs - TCP/IP transport with blocking API
  • examples/quickstart_async.rs - TCP/IP transport with async API
  • examples/transports.rs - Protocol and transport comparisons
  • examples/transport_builder_demo.rs - Transport configuration patterns

§Async Support

The library provides runtime-agnostic async support, allowing you to use ANY async runtime (tokio, smol, etc.) or even create your own.

§Feature Flags

  • mode-async - Enables async support without any specific runtime. You must provide your own runtime.
  • Blocking API - Baseline API when mode-async is not enabled.
  • runtime-tokio - Enables async with built-in Tokio runtime support (implies mode-async).
  • runtime-smol - Enables async with built-in smol runtime support (implies mode-async).
  • transport-serial - Enables serial port support for blocking mode.
  • transport-serial-tokio - Enables serial port support with Tokio (implies runtime-tokio).
  • test-utils - Deterministic test transports and executors for crate and downstream tests.

Multiple Runtime Support: Runtime features can be enabled simultaneously. This allows libraries to support multiple runtime ecosystems without forcing users to choose. Pass the runtime explicitly to Connect or CameraConfig when multiple runtime features are available.

§Send Future Guarantees

All public async traits in this crate guarantee that their returned futures are Send. This is enforced through explicit + Send bounds in trait signatures using return-position impl trait in traits (RPITIT).

This guarantee ensures spawn-safety across all async runtimes and prevents subtle !Send future errors in multi-threaded executors.

§Runtime Requirements for Async

The async API REQUIRES a runtime to be configured. Without a runtime, ALL async operations will fail with: Error::InvalidState("No runtime configured for async operations").

The runtime is essential for:

  • Timeout handling - All camera commands have configurable timeouts
  • Power sequences - Power on/off operations require delays
  • Movement detection - Polling for pan/tilt/zoom completion
  • Background tasks - Socket manager for concurrent operations

§Runtime Requirements for Async

You have multiple options for configuring a runtime:

§Option 1: Use built-in runtime support (Easiest)

Choose your runtime(s) and enable the corresponding feature(s) in Cargo.toml:

[dependencies]
# Single runtime:
grafton-visca = { version = "1", features = ["runtime-tokio"] }
grafton-visca = { version = "1", features = ["runtime-smol"] }

# Multiple runtimes (choose executor at construction time):
grafton-visca = { version = "1", features = ["runtime-tokio", "runtime-smol"] }

Then pass the runtime explicitly, either through Connect for quick setup or CameraBuilder::with_executor(...) for advanced BYO-transport flows:

// Tokio
use grafton_visca::{camera::{Connect, profiles::PtzOpticsG2}, runtime::TokioRuntime};
let runtime = TokioRuntime::from_current()?;
let camera = Connect::open_tcp_async::<PtzOpticsG2, _>("192.168.0.110", runtime).await?;

// smol
use grafton_visca::{camera::{Connect, profiles::PtzOpticsG2}, runtime::SmolRuntime};
let runtime = SmolRuntime::new();
let camera = Connect::open_tcp_async::<PtzOpticsG2, _>("192.168.0.110", runtime).await?;
§Option 2: Provide your own runtime (Advanced)

For complete runtime independence, implement Executor and attach your own async transport with CameraBuilder::from_transport(...):

use grafton_visca::{
    CameraBuilder, Error, ExecError, Executor,
    camera::profiles::PtzOpticsG2,
};
use std::{future::Future, pin::Pin, time::Duration};

#[derive(Debug, Clone)]
struct MyExecutor;

impl Executor for MyExecutor {
    type Join<T> = Pin<Box<dyn Future<Output = Result<T, ExecError>> + Send + 'static>>
    where T: Send + 'static;

    type Detach = ();

    fn spawn_with_detach<F>(&self, fut: F) -> (Self::Join<F::Output>, Self::Detach)
    where
        F: Future + Send + 'static,
        F::Output: Send + 'static,
    {
        // Spawn on your runtime here
    }

    fn block_on<F: Future>(&self, fut: F) -> F::Output {
        todo!()
    }

    fn sleep(&self, duration: Duration) -> impl Future<Output = ()> + Send + '_ {
        async move {
            let _ = duration;
        }
    }

    fn timeout<'a, F, T>(
        &'a self,
        duration: Duration,
        fut: F,
    ) -> impl Future<Output = Result<T, Error>> + Send + 'a
    where
        F: Future<Output = T> + Send + 'a,
        T: Send + 'a,
    {
        async move {
            let _ = duration;
            Ok(fut.await)
        }
    }
}

async fn main() -> Result<(), Error> {
    let transport = MyAsyncTransport::connect("192.168.0.110:5678").await?;
    let camera = CameraBuilder::with_executor(MyExecutor)
        .from_transport(transport)
        .profile::<PtzOpticsG2>()
        .open_async()
        .await?;

    camera.power().on().await?;
    Ok(())
}

See examples/runtime_agnostic.rs for a complete end-to-end example.

§Common Runtime Errors and Solutions

§Error: InvalidState("No runtime configured for async operations")

Cause: You’re using async mode but haven’t configured a runtime. Solution: Either:

  • Enable runtime-tokio and pass TokioRuntime::from_current()? to Connect or CameraConfig
  • Use CameraBuilder::with_executor() only when attaching your own transport/runtime implementation
§Error: InvalidState("Operation requires runtime for timeout handling")

Cause: The operation needs timeout support but no runtime is available. Solution: Same as above - configure a runtime.

§Error: Socket manager initialization issues

Cause: The socket manager requires a runtime to spawn background tasks. Solution: Ensure your runtime’s Spawner implementation is working correctly.

§Blocking vs Async Mode

The library provides a clean separation between blocking and async APIs:

  • Blocking mode (default): No async dependencies, uses synchronous I/O

    • When no features are enabled, only blocking types are available
    • Zero async runtime overhead or dependencies
  • Async mode (mode-async feature): Native async implementation

    • When mode-async feature is enabled, blocking types are NOT exported
    • Provides true async I/O without blocking thread pools
    • REQUIRES runtime configuration (see Async Support section above)

The API surface changes based on your feature selection - you get either blocking OR async types, never both. This ensures a clean, focused API for your use case.

§Supported Commands

§Camera Movement

  • Pan/Tilt/Zoom control with absolute and relative positioning
  • Variable speed control for smooth movements
  • Home position and preset management

§Exposure & Color

  • Exposure modes: Auto, Manual, Shutter Priority, Iris Priority, Bright
  • White balance modes including manual color temperature
  • Color adjustments: saturation, hue, RGB gain tuning

§Image Control

  • Focus control with auto/manual modes
  • Sharpness, brightness, and contrast adjustment
  • Noise reduction (2D and 3D)
  • Image flip and other effects

§Position Units

The Camera API supports multiple position unit types with automatic conversion:

// Work in degrees (recommended)
camera.pan_tilt().absolute(Degrees(45.0), Degrees(-15.0), SpeedLevel::Medium)?;

// Stop all movement
camera.pan_tilt().stop()?;

// Move to home position
camera.pan_tilt().home()?;

§Timeout Configuration

Configure timeouts per command category based on your network and camera:

use grafton_visca::{camera::{CameraConfig, profiles::PtzOpticsG2}, TimeoutConfig};
use std::time::Duration;

let config = TimeoutConfig::builder()
    .ack_timeout(Duration::from_millis(300))
    .quick_timeout(Duration::from_secs(3))
    .movement_timeout(Duration::from_secs(20))
    .preset_timeout(Duration::from_secs(60))
    .build();

// For async mode
use grafton_visca::runtime::TokioRuntime;
let runtime = TokioRuntime::from_current()?;
let camera = CameraConfig::<PtzOpticsG2>::tcp("192.168.0.110")
    .timeouts(config)
    .open_async(runtime)
    .await?;

// For blocking mode (when async feature is disabled)
#[cfg(not(feature = "mode-async"))]
let camera = CameraConfig::<PtzOpticsG2>::tcp("192.168.0.110")
    .timeouts(config)
    .open_blocking()?;

§Command Cancellation (Async)

Cancel specific commands or entire socket operations:

// Send a command and get its ID for cancellation
let (cmd_id, response_future) = camera.send_command_with_id(command).await?;

// Cancel the specific command
camera.cancel_command(cmd_id).await?;

// Or cancel all commands on a socket
use grafton_visca::ViscaSocket;
camera.cancel_socket(ViscaSocket::S1).await?;

§Movement Completion Tracking

Wait for camera movements to complete using AwaitConfig:

use std::time::Duration;
use grafton_visca::camera::{AwaitConfig, Axes};

// Start a pan/tilt movement
camera
    .pan_tilt()
    .absolute(Degrees(45.0), Degrees(15.0), SpeedLevel::Medium)
    .await?;

// Wait for all movements to complete (pan/tilt, zoom, focus)
camera.await_idle(Duration::from_secs(30)).await?;

// Or wait for specific axes with custom configuration
let config = AwaitConfig::new(Duration::from_secs(10))
    .with_axes(Axes::PAN_TILT)
    .with_debug();
camera.await_with_config(&config).await?;

// Convenience methods for common scenarios
camera.await_pan_tilt_idle(Duration::from_secs(20)).await?;
camera.await_zoom_idle(Duration::from_secs(15)).await?;

§Error Handling

The library provides comprehensive error types for all VISCA error conditions:

match camera
    .pan_tilt()
    .absolute(Degrees(180.0), Degrees(0.0), SpeedLevel::Medium)
    .await
{
    Ok(_) => println!("Position set successfully"),
    Err(Error::SyntaxError) => println!("Position out of range"),
    Err(Error::CommandNotExecutable) => println!("Camera busy or powered off"),
    Err(Error::CommandBufferFull) => {
        // This error is automatically retried by the runtime
        println!("Camera buffer full, command will retry");
    }
    Err(e) => println!("Other error: {e}"),
}

Re-exports§

pub use crate::camera::Camera;
pub use crate::camera::CameraBuilder;
pub use crate::command::AutoFocusSensitivity;
pub use crate::command::AutoWhiteBalanceSensitivity;
pub use crate::command::ExposureMode;
pub use crate::command::FocusMode;
pub use crate::command::MotionSyncMode;
pub use crate::command::MotionSyncPreset;
pub use crate::command::NdFilterMode;
pub use crate::command::NdFilterPosition;
pub use crate::command::PanTiltDirection;
pub use crate::command::PanTiltLimitCorner;
pub use crate::command::PictureEffectMode;
pub use crate::command::PresetNumber;
pub use crate::command::ResolutionMode;
pub use crate::command::WhiteBalanceMode;
pub use crate::inquiry_conversions::zoom_from_normalized;
pub use crate::inquiry_conversions::PanTiltPositionDeg;
pub use crate::inquiry_conversions::PanTiltPositionRaw;
pub use crate::inquiry_conversions::ZoomDomain;
pub use crate::inquiry_conversions::ZoomPositionExt;
pub use crate::types::Coarse;
pub use crate::types::FocusSpeed;
pub use crate::types::MotionSyncSpeed;
pub use crate::types::SpeedLevel;
pub use crate::types::ZoomSpeed;
pub use crate::units::UnitInterval;
pub use crate::camera::BlockingCamera;
pub use crate::camera::BlockingClient;

Modules§

camera
Camera profile system for type-safe, model-specific control Camera-first, profile-centric VISCA API.
capabilities
Capability traits for camera feature composition Fine-grained capability traits for VISCA camera features.
command
Low-level VISCA command definitions and extension traits.
inquiry_conversions
Inquiry conversion utilities for raw to user-friendly values Inquiry conversion utilities for converting raw VISCA values to user-friendly formats.
mode
Mode trait system for unified async/blocking API.
prelude
Prelude modules for convenient imports.
profiles
Camera profiles with compositional capabilities
runtime
VISCA runtime with flume-based scheduling VISCA runtime implementation using flume channels.
timeout
Unified timeout configuration and management for VISCA commands.
transport
Transport layer for implementing custom transports Transport layer for VISCA communication.
types
Type definitions and abstractions Type-safe wrappers for VISCA protocol values.
units
Semantic unit types for intuitive API usage Semantic unit types for VISCA protocol values.

Macros§

impl_camera_ops
Generate trait implementations that forward to inherent methods on Camera.
visca_command
Create a VISCA command that expects ACK/Completion responses.
visca_range_type
Create a type with range validation.

Structs§

CachedFlipState
Cached flip state for image orientation.
CameraId
Represents a VISCA camera ID for addressing commands.
StateCache
Cached state for write-only properties (blocking mode).

Enums§

Error
VISCA protocol error type.
ErrorKind
Categorized error kinds for structured error handling.
PanTiltLimits
Limits for pan/tilt movement.
ViscaSocket
VISCA socket identifier.

Traits§

AutoFocusSensitivityControl
Auto-focus sensitivity control for profiles with documented support.
AutoFocusSensitivityInquiryControl
Auto-focus sensitivity inquiry for profiles with documented support.
AutoTrackingWhiteBalanceControl
Auto-tracking white balance operations for profiles with documented support.
AutoWhiteBalanceSensitivityControl
Auto white-balance sensitivity operations for profiles with documented support.
BacklightCompensationControl
Backlight compensation operations for profiles with documented support.
BacklightCompensationInquiryControl
Backlight compensation inquiry for profiles with documented support.
BrightnessControl
Exposure brightness operations for profiles with documented bright control support.
BrightnessInquiryControl
Exposure brightness inquiry for profiles with documented support.
ColorControl
Color operations for PTZ cameras.
ColorTemperatureControl
Color-temperature operations for profiles with documented support.
ColorTemperatureInquiryControl
Color-temperature inquiry for profiles with documented support.
ContrastControl
Contrast operations for profiles with documented support.
ContrastInquiryControl
Contrast inquiry for profiles with documented support.
DigitalZoomControl
VISCA digital zoom toggle for profiles that document the enable/disable opcode.
DigitalZoomRangeControl
Absolute zoom positioning across a documented optical-plus-digital range.
DirectMenuControl
Direct menu control methods for cameras that support advanced menu control.
DirectZoomControl
Direct absolute zoom positioning for profiles with source-backed support.
ExposureCompensationControl
Exposure compensation operations for cameras.
ExposureCompensationInquiryControl
Exposure-compensation inquiries for profiles with documented support.
ExposureControl
Exposure operations for PTZ cameras.
FocusControl
Focus operations for PTZ cameras.
FocusLockControl
Focus lock control for cameras that support focus locking.
FocusNearLimitInquiryControl
Focus near-limit inquiry for profiles with documented support.
FocusZoneControl
Focus zone selection for profiles with documented support.
FocusZoneInquiryControl
Focus zone inquiry for profiles with documented support.
GammaControl
Gamma operations for profiles with documented support.
GammaInquiryControl
Gamma inquiry for profiles with documented support.
HueControl
Hue operations for profiles with documented support.
HueInquiryControl
Hue inquiry for profiles with documented support.
ImageFlipControl
Vertical image flip operations for profiles with documented support.
ImageFlipInquiryControl
Image flip inquiry for profiles with documented support.
ImageFlipModeControl
Combined image flip-mode operations for profiles using the combined opcode.
ImageMirrorControl
Horizontal image mirror operations for profiles with documented support.
InquiryControl
Inquiry operations for PTZ cameras.
IrisControl
Iris operations for profiles with source-backed iris support.
IrisInquiryControl
Iris value inquiry for profiles with documented iris support.
LuminanceControl
Luminance operations for profiles with documented support.
LuminanceInquiryControl
Luminance inquiry for profiles with documented support.
MenuControl
Menu control methods for cameras that support menu navigation.
MotionControl
Motion control operations for PTZ cameras.
MotionSyncControl
Motion sync control methods for cameras that support this feature.
NdFilterControl
ND filter operations for PTZ cameras.
NdFilterInquiryControl
ND filter-specific inquiry operations for cameras with typed ND filter support.
NoiseReduction2DControl
2D noise-reduction operations for profiles with documented support.
NoiseReduction2DInquiryControl
2D noise-reduction inquiry for profiles with documented support.
NoiseReduction3DControl
3D noise-reduction operations for profiles with documented support.
NoiseReduction3DInquiryControl
3D noise-reduction inquiry for profiles with documented support.
NoiseReductionInquiryControl
Aggregate noise-reduction inquiries for profiles with documented support.
OnePushFocusControl
Standard one-push auto-focus for profiles with documented support.
OnePushWhiteBalanceControl
One-push white balance operations for profiles with documented support.
PanTiltControl
Pan/Tilt operations for PTZ cameras.
PanTiltInquiryControl
Pan/tilt-specific inquiry operations for cameras.
PictureEffectControl
Picture-effect operations for profiles with documented support.
PictureEffectInquiryControl
Picture-effect inquiries for profiles with documented support.
PowerControl
Power operations for PTZ cameras.
PresetsControl
Preset operations for PTZ cameras.
PushAFControl
Push AF control for cameras that support temporary auto focus.
RgbGainControl
Manual red/blue gain operations for profiles with documented support.
RgbGainInquiryControl
RGB gain inquiries for profiles with documented support.
RgbTuningControl
Red/blue tuning operations for profiles with documented support.
RgbTuningInquiryControl
RGB tuning inquiries for profiles with documented support.
SaturationControl
Saturation operations for profiles with documented support.
SaturationInquiryControl
Saturation inquiry for profiles with documented support.
SharpnessControl
Sharpness operations for profiles with documented support.
SharpnessInquiryControl
Sharpness inquiries for profiles with documented support.
SnapFocusControl
PTZOptics snap focus for profiles with documented support.
StreamingControl
Streaming operations for PTZ cameras.
SystemControl
System operations for PTZ cameras.
TallyControl
Tally light control operations for cameras.
VariableSpeedControl
Variable speed mode control for cameras.
WhiteBalanceControl
White balance operations for PTZ cameras.
WideDynamicRangeControl
Wide dynamic range operations for profiles with documented support.
WideDynamicRangeInquiryControl
Wide dynamic range inquiry for profiles with documented support.
ZoomControl
Zoom operations for PTZ cameras.

Type Aliases§

Result
Custom result type for VISCA operations.

Derive Macros§

ViscaEnum
Derive macro for automatic enum/u8 conversions in VISCA protocol
ViscaInquiry
Derive macro for generating ViscaCommand inquiry implementations with parser support.
ViscaValue
Derive macro for implementing ViscaValue trait for command value types