Skip to main content

grafton_visca/command/
variable_speed.rs

1//! Variable speed mode commands for Sony FR7.
2//!
3//! The FR7 supports switching between 24-step and 50-step speed modes for pan/tilt control.
4//! When in 50-step mode, pan/tilt speed values can range from 1-50 for finer control.
5
6use crate::{
7    command::{bytes::builder::ConstCommandBuilder, encode::ViscaCommand},
8    error::Error,
9    timeout::CommandCategory,
10};
11
12/// Variable speed mode setting for Sony FR7.
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
16#[cfg_attr(feature = "ts-rs", derive(ts_rs::TS), ts(export))]
17#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
18pub enum VariableSpeedMode {
19    /// Standard 24-step speed mode (1-24 speeds).
20    Standard24,
21    /// Fine 50-step speed mode (1-50 speeds).
22    Fine50,
23}
24
25/// Command to set variable speed mode on Sony FR7.
26///
27/// # Sony FR7 Specific
28/// Command: `81 01 7E 04 1B 0p FF`
29/// - p = 1 (24-step mode)
30/// - p = 2 (50-step mode)
31#[derive(Debug, Clone, Copy)]
32pub struct SetVariableSpeedMode {
33    /// The speed mode to set.
34    pub mode: VariableSpeedMode,
35}
36
37impl SetVariableSpeedMode {
38    /// Create a new variable speed mode command.
39    pub fn new(mode: VariableSpeedMode) -> Self {
40        Self { mode }
41    }
42}
43
44impl ViscaCommand for SetVariableSpeedMode {
45    const MAX_SIZE: usize = 7;
46    const TIMEOUT_CATEGORY: CommandCategory = CommandCategory::Quick;
47
48    fn write_into(
49        &self,
50        camera_id: crate::camera_id::CameraId,
51        buffer: &mut [u8],
52    ) -> Result<usize, Error> {
53        use crate::command::bytes::constants;
54
55        let mode_byte = match self.mode {
56            VariableSpeedMode::Standard24 => 0x01,
57            VariableSpeedMode::Fine50 => 0x02,
58        };
59
60        ConstCommandBuilder::<7>::from_prefix(constants::variable_speed::CONTROL_PREFIX)
61            .with_camera_id(camera_id)
62            .push(mode_byte)
63            .terminate()
64            .build_into(buffer)
65    }
66}
67
68#[cfg(test)]
69mod tests {
70    use super::*;
71    use crate::command::bytes::VISCA_TERMINATOR;
72    use crate::macros::test_utils::visca_test;
73
74    visca_test!(
75        SetVariableSpeedMode,
76        test_variable_speed_mode_standard24,
77        SetVariableSpeedMode::new(VariableSpeedMode::Standard24),
78        &[0x81, 0x01, 0x7E, 0x04, 0x1B, 0x01, VISCA_TERMINATOR]
79    );
80
81    visca_test!(
82        SetVariableSpeedMode,
83        test_variable_speed_mode_fine50,
84        SetVariableSpeedMode::new(VariableSpeedMode::Fine50),
85        &[0x81, 0x01, 0x7E, 0x04, 0x1B, 0x02, VISCA_TERMINATOR]
86    );
87}