[INFO] fetching crate bluerobotics-ping 0.3.6...
[INFO] checking bluerobotics-ping-0.3.6 against c60b92c03ca8a3b101eb9d57f51e2232690638c7 for pr-164148-crater-rollup
[INFO] extracting crate bluerobotics-ping 0.3.6 into /workspace/builds/worker-1-tc2/source
[INFO] started tweaking crates.io crate bluerobotics-ping 0.3.6
[INFO] removed 0 missing examples
[INFO] removed 0 missing tests
[INFO] finished tweaking crates.io crate bluerobotics-ping 0.3.6
[INFO] tweaked toml for crates.io crate bluerobotics-ping 0.3.6 written to /workspace/builds/worker-1-tc2/source/Cargo.toml
[INFO] validating manifest of crates.io crate bluerobotics-ping 0.3.6 on toolchain c60b92c03ca8a3b101eb9d57f51e2232690638c7
[INFO] running `Command { std: CARGO_HOME="/workspace/cargo-home" RUSTUP_HOME="/workspace/rustup-home" "/workspace/cargo-home/bin/cargo" "+c60b92c03ca8a3b101eb9d57f51e2232690638c7" "metadata" "--manifest-path" "Cargo.toml" "--no-deps", kill_on_drop: false }`
[INFO] crate crates.io crate bluerobotics-ping 0.3.6 already has a lockfile, it will not be regenerated
[INFO] running `Command { std: CARGO_HOME="/workspace/cargo-home" RUSTUP_HOME="/workspace/rustup-home" "/workspace/cargo-home/bin/cargo" "+c60b92c03ca8a3b101eb9d57f51e2232690638c7" "fetch" "--manifest-path" "Cargo.toml", kill_on_drop: false }`
[INFO] running `Command { std: "docker" "create" "-v" "/var/lib/crater-agent-workspace/builds/worker-1-tc2/source:/opt/rustwide/workdir:ro,Z" "-v" "/var/lib/crater-agent-workspace/builds/worker-1-tc2/target:/opt/rustwide/target:rw,Z" "-v" "/var/lib/crater-agent-workspace/cargo-home:/opt/rustwide/cargo-home:ro,Z" "-v" "/var/lib/crater-agent-workspace/rustup-home:/opt/rustwide/rustup-home:ro,Z" "-m" "1610612736" "--network" "none" "ghcr.io/rust-lang/crates-build-env/linux@sha256:77db811e55d90add9212f6832c23229e3de5f1c1f9905e8cb07319ea15df73ac" "sleep" "infinity", kill_on_drop: false }`
[INFO] [stdout] 3f1ee2b8eb0ebbbb0de7cf14c91902262af1c5c7d62903810f61289ca09c8f7c
[INFO] running `Command { std: "docker" "start" "3f1ee2b8eb0ebbbb0de7cf14c91902262af1c5c7d62903810f61289ca09c8f7c", kill_on_drop: false }`
[INFO] running `Command { std: "docker" "inspect" "3f1ee2b8eb0ebbbb0de7cf14c91902262af1c5c7d62903810f61289ca09c8f7c", kill_on_drop: false }`
[INFO] running `Command { std: "docker" "exec" "-e" "SOURCE_DIR=/opt/rustwide/workdir" "-e" "CARGO_HOME=/opt/rustwide/cargo-home" "-e" "RUSTUP_HOME=/opt/rustwide/rustup-home" "-e" "CARGO_TARGET_DIR=/opt/rustwide/target" "-w" "/opt/rustwide/workdir" "--user" "0:0" "3f1ee2b8eb0ebbbb0de7cf14c91902262af1c5c7d62903810f61289ca09c8f7c" "/opt/rustwide/cargo-home/bin/cargo" "+c60b92c03ca8a3b101eb9d57f51e2232690638c7" "metadata" "--no-deps" "--format-version=1", kill_on_drop: false }`
[INFO] running `Command { std: "docker" "inspect" "3f1ee2b8eb0ebbbb0de7cf14c91902262af1c5c7d62903810f61289ca09c8f7c", kill_on_drop: false }`
[INFO] running `Command { std: "docker" "exec" "-e" "SOURCE_DIR=/opt/rustwide/workdir" "-e" "CARGO_HOME=/opt/rustwide/cargo-home" "-e" "RUSTUP_HOME=/opt/rustwide/rustup-home" "-e" "CARGO_TARGET_DIR=/opt/rustwide/target" "-e" "CARGO_INCREMENTAL=0" "-e" "RUST_BACKTRACE=full" "-e" "RUSTFLAGS=--cap-lints=forbid" "-e" "RUSTDOCFLAGS=--cap-lints=forbid" "-w" "/opt/rustwide/workdir" "--user" "0:0" "3f1ee2b8eb0ebbbb0de7cf14c91902262af1c5c7d62903810f61289ca09c8f7c" "/opt/rustwide/cargo-home/bin/cargo" "+c60b92c03ca8a3b101eb9d57f51e2232690638c7" "check" "--frozen" "--all" "--all-targets" "--message-format=json", kill_on_drop: false }`
[INFO] [stderr]    Compiling libc v0.2.172
[INFO] [stderr]     Checking smallvec v1.15.0
[INFO] [stderr]     Checking bytes v1.11.0
[INFO] [stderr]    Compiling proc-macro2 v1.0.103
[INFO] [stderr]    Compiling num-traits v0.2.19
[INFO] [stderr]     Checking tracing-core v0.1.33
[INFO] [stderr]     Checking lock_api v0.4.12
[INFO] [stderr]     Checking regex-automata v0.4.9
[INFO] [stderr]    Compiling serde_core v1.0.228
[INFO] [stderr]     Checking serde_json v1.0.145
[INFO] [stderr]    Compiling ref-cast v1.0.24
[INFO] [stderr]    Compiling nix v0.29.0
[INFO] [stderr]    Compiling serde v1.0.228
[INFO] [stderr]    Compiling memchr v2.7.4
[INFO] [stderr]    Compiling unicode-segmentation v1.12.0
[INFO] [stderr]     Checking clap_builder v4.5.53
[INFO] [stderr]     Checking half v2.6.0
[INFO] [stderr]     Checking rayon-core v1.12.1
[INFO] [stderr]     Checking ciborium-ll v0.2.2
[INFO] [stderr]     Checking thread_local v1.1.8
[INFO] [stderr]     Checking tracing-log v0.2.0
[INFO] [stderr]    Compiling convert_case v0.10.0
[INFO] [stderr]     Checking criterion-plot v0.6.0
[INFO] [stderr]     Checking rayon v1.10.0
[INFO] [stderr]    Compiling quote v1.0.42
[INFO] [stderr]     Checking http v1.3.1
[INFO] [stderr]     Checking num-integer v0.1.46
[INFO] [stderr]     Checking num-complex v0.4.6
[INFO] [stderr]     Checking plotters v0.3.7
[INFO] [stderr]    Compiling syn v2.0.100
[INFO] [stderr]     Checking num-bigint v0.4.6
[INFO] [stderr]     Checking num-iter v0.1.45
[INFO] [stderr]     Checking http-body v1.0.1
[INFO] [stderr]     Checking http-body-util v0.1.3
[INFO] [stderr]     Checking parking_lot_core v0.9.10
[INFO] [stderr]     Checking mio v1.0.3
[INFO] [stderr]     Checking signal-hook-registry v1.4.5
[INFO] [stderr]     Checking socket2 v0.6.1
[INFO] [stderr]     Checking getrandom v0.3.4
[INFO] [stderr]     Checking nix v0.26.4
[INFO] [stderr]     Checking socket2 v0.5.9
[INFO] [stderr]     Checking rand_core v0.9.3
[INFO] [stderr]     Checking parking_lot v0.12.3
[INFO] [stderr]     Checking rand_chacha v0.9.0
[INFO] [stderr]     Checking rand v0.9.2
[INFO] [stderr]     Checking num-rational v0.4.2
[INFO] [stderr]     Checking num v0.4.3
[INFO] [stderr]     Checking fraction v0.15.3
[INFO] [stderr]     Checking regex v1.11.1
[INFO] [stderr]     Checking matchers v0.2.0
[INFO] [stderr]     Checking fancy-regex v0.16.2
[INFO] [stderr]    Compiling synstructure v0.13.2
[INFO] [stderr]    Compiling serde_derive v1.0.228
[INFO] [stderr]    Compiling zerovec-derive v0.11.1
[INFO] [stderr]    Compiling displaydoc v0.2.5
[INFO] [stderr]    Compiling tokio-macros v2.6.0
[INFO] [stderr]    Compiling futures-macro v0.3.31
[INFO] [stderr]    Compiling tracing-attributes v0.1.28
[INFO] [stderr]    Compiling thiserror-impl v1.0.69
[INFO] [stderr]    Compiling derive_arbitrary v1.4.1
[INFO] [stderr]    Compiling ref-cast-impl v1.0.24
[INFO] [stderr]    Compiling clap_derive v4.5.49
[INFO] [stderr]    Compiling tracing-test-macro v0.2.5
[INFO] [stderr]    Compiling zerofrom-derive v0.1.6
[INFO] [stderr]    Compiling yoke-derive v0.8.0
[INFO] [stderr]     Checking tokio v1.48.0
[INFO] [stderr]    Compiling arbitrary v1.4.2
[INFO] [stderr]     Checking futures-util v0.3.31
[INFO] [stderr]     Checking tracing v0.1.41
[INFO] [stderr]     Checking zerofrom v0.1.6
[INFO] [stderr]     Checking tracing-subscriber v0.3.20
[INFO] [stderr]     Checking yoke v0.8.0
[INFO] [stderr]     Checking clap v4.5.53
[INFO] [stderr]     Checking zerovec v0.11.2
[INFO] [stderr]     Checking zerotrie v0.2.2
[INFO] [stderr]     Checking thiserror v1.0.69
[INFO] [stderr]     Checking unescaper v0.1.5
[INFO] [stderr]     Checking serialport v4.7.1
[INFO] [stderr]     Checking mio-serial v5.0.6
[INFO] [stderr]     Checking tracing-test v0.2.5
[INFO] [stderr]     Checking tinystr v0.8.1
[INFO] [stderr]     Checking potential_utf v0.1.2
[INFO] [stderr]     Checking icu_collections v2.0.0
[INFO] [stderr]     Checking icu_locale_core v2.0.0
[INFO] [stderr]     Checking serde_urlencoded v0.7.1
[INFO] [stderr]     Checking ahash v0.8.12
[INFO] [stderr]     Checking fluent-uri v0.4.1
[INFO] [stderr]     Checking ciborium v0.2.2
[INFO] [stderr]     Checking email_address v0.2.9
[INFO] [stderr]     Checking tinytemplate v1.2.1
[INFO] [stderr]    Compiling bluerobotics-ping v0.3.6 (/opt/rustwide/workdir)
[INFO] [stderr]     Checking referencing v0.37.1
[INFO] [stderr]     Checking icu_provider v2.0.0
[INFO] [stderr]     Checking icu_normalizer v2.0.0
[INFO] [stderr]     Checking icu_properties v2.0.1
[INFO] [stderr]     Checking futures-executor v0.3.31
[INFO] [stderr]     Checking futures v0.3.31
[INFO] [stderr]     Checking idna_adapter v1.2.1
[INFO] [stderr]     Checking idna v1.0.3
[INFO] [stderr]     Checking url v2.5.4
[INFO] [stderr]     Checking hyper v1.6.0
[INFO] [stderr]     Checking tower v0.5.2
[INFO] [stderr]     Checking tokio-serial v5.4.5
[INFO] [stderr]     Checking tokio-util v0.7.17
[INFO] [stderr]     Checking criterion v0.7.0
[INFO] [stderr]     Checking udp-stream v0.0.12
[INFO] [stderr]     Checking tower-http v0.6.6
[INFO] [stderr]     Checking hyper-util v0.1.14
[INFO] [stderr]     Checking reqwest v0.12.20
[INFO] [stdout] warning: variable does not need to be mutable
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:9525
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePa...
[INFO] [stdout]   |                                                       ----^^^^^^
[INFO] [stdout]   |                                                       |
[INFO] [stdout]   |                                                       help: remove this `mut`
[INFO] [stdout]   |
[INFO] [stdout]   = note: `#[warn(unused_mut)]` (part of `#[warn(unused)]`) on by default
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] warning: unused variable: `payload`
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:9647
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...fStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16...
[INFO] [stdout]   |                              ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_payload`
[INFO] [stdout]   |
[INFO] [stdout]   = note: `#[warn(unused_variables)]` (part of `#[warn(unused)]`) on by default
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] warning: variable does not need to be mutable
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/bluebps.rs:1:24169
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePa...
[INFO] [stdout]   |                                                       ----^^^^^^
[INFO] [stdout]   |                                                       |
[INFO] [stdout]   |                                                       help: remove this `mut`
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] warning: unused variable: `payload`
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/bluebps.rs:1:24293
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...hStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for EraseFlashStruct { fn id () -> u16 { 9201u...
[INFO] [stdout]   |                              ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_payload`
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] warning: variable does not need to be mutable
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/bluebps.rs:1:25021
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePa...
[INFO] [stdout]   |                                                       ----^^^^^^
[INFO] [stdout]   |                                                       |
[INFO] [stdout]   |                                                       help: remove this `mut`
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] warning: unused variable: `payload`
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/bluebps.rs:1:25148
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...sStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for ResetDefaultsStruct { fn id () -> u16 { 92...
[INFO] [stdout]   |                              ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_payload`
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] warning: variable does not need to be mutable
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping1d.rs:1:49324
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePa...
[INFO] [stdout]   |                                                       ----^^^^^^
[INFO] [stdout]   |                                                       |
[INFO] [stdout]   |                                                       help: remove this `mut`
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] warning: unused variable: `payload`
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping1d.rs:1:49452
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...rStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for GotoBootloaderStruct { fn id () -> u16 { 1...
[INFO] [stdout]   |                              ^^^^^^^ help: if this is intentional, prefix it with an underscore: `_payload`
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stderr]     Checking jsonschema v0.37.1
[INFO] [stdout] error: useless conversion to the same type: `String` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/mod.rs:1:2824
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...MSG_SIZE { return Err (format ! ("Message is too short, should be at least {MIN_MSG_SIZE} bytes") . into ()) ; } let payload_lengt...
[INFO] [stdout]   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout]   = note: `#[deny(self_type_conversion)]` on by default
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:7209
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...erialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , trans...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : <u8 as Into<_>>::into(payload [0usize]) , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:7253
[INFO] [stdout]   |
[INFO] [stdout] 1 | ... mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : <u8 as Into<_>>::into(payload [1usize]) , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:8044
[INFO] [stdout]   |
[INFO] [stdout] 1 | ... () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl ...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : <u8 as Into<_>>::into(payload [14usize]) , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:8082
[INFO] [stdout]   |
[INFO] [stdout] 1 | ... num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { f...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : <u8 as Into<_>>::into(payload [15usize]) , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:14181
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...erialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : <u8 as Into<_>>::into(payload [0usize]) , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:14225
[INFO] [stdout]   |
[INFO] [stdout] 1 | ... mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. ...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : <u8 as Into<_>>::into(payload [1usize]) , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:14887
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...o () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } im...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : <u8 as Into<_>>::into(payload [12usize]) , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:14928
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ransmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn ...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : <u8 as Into<_>>::into(payload [13usize]) , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:16173
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...eserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } imp...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : <u8 as Into<_>>::into(payload [0usize]) , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:16213
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : <u8 as Into<_>>::into(payload [1usize]) , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:21849
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...erialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : <u8 as Into<_>>::into(payload [0usize]) , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:21893
[INFO] [stdout]   |
[INFO] [stdout] 1 | ... mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. ...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : <u8 as Into<_>>::into(payload [1usize]) , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:22672
[INFO] [stdout]   |
[INFO] [stdout] 1 | ... () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_s...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : <u8 as Into<_>>::into(payload [14usize]) , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:22710
[INFO] [stdout]   |
[INFO] [stdout] 1 | ... num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : <u8 as Into<_>>::into(payload [15usize]) , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:27901
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...erialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : <u8 as Into<_>>::into(payload [0usize]) , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:27945
[INFO] [stdout]   |
[INFO] [stdout] 1 | ... mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. ...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : <u8 as Into<_>>::into(payload [1usize]) , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:31099
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ze (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } imp...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : <u8 as Into<_>>::into(payload [0usize]) , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping360.rs:1:31139
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id ()...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { AutoTransmit (AutoTransmitStruct) , MotorOff (MotorOffStruct) , Transducer (TransducerStruct) , SetDeviceId (SetDeviceIdStruct) , AutoDeviceData (AutoDeviceDataStruct) , DeviceData (DeviceDataStruct) , Reset (ResetStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: AutoTransmit (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: MotorOff (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Transducer (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AutoDeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceData (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reset (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] pub struct AutoTransmitStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , } impl SerializePayload for AutoTransmitStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer } } impl DeserializePayload for AutoTransmitStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , transmit_duration : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , } } } impl MessageInfo for AutoTransmitStruct { fn id () -> u16 { 2602u16 } fn name () -> & 'static str { "auto_transmit" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] pub struct MotorOffStruct { } impl SerializePayload for MotorOffStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for MotorOffStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for MotorOffStruct { fn id () -> u16 { 2903u16 } fn name () -> & 'static str { "motor_off" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] pub struct TransducerStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"))] pub transmit : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for TransducerStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransducerStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit : payload [12usize] . into () , reserved : payload [13usize] . into () , } } } impl MessageInfo for TransducerStruct { fn id () -> u16 { 2601u16 } fn name () -> & 'static str { "transducer" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Change the device id"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Change the device id"] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 and 255 are reserved."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 and 255 are reserved."))] pub id : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : payload [0usize] . into () , reserved : payload [1usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 2000u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub struct AutoDeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."))] pub start_angle : u16 , # [doc = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."))] pub stop_angle : u16 , # [doc = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"))] pub num_steps : u8 , # [doc = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] # [cfg_attr (feature = "schemars" , schemars (description = "An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."))] pub delay : u8 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for AutoDeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . stop_angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_steps . to_le_bytes ()) ; buffer . extend_from_slice (& self . delay . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for AutoDeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , start_angle : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , stop_angle : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_steps : payload [14usize] . into () , delay : payload [15usize] . into () , number_of_samples : u16 :: from_le_bytes (payload [16usize .. 16usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [18usize .. 18usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [18usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for AutoDeviceDataStruct { fn id () -> u16 { 2301u16 } fn name () -> & 'static str { "auto_device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub struct DeviceDataStruct { # [doc = "Operating mode (1 for Ping360)"] # [cfg_attr (feature = "schemars" , schemars (description = "Operating mode (1 for Ping360)"))] pub mode : u8 , # [doc = "Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [cfg_attr (feature = "schemars" , schemars (description = "Analog gain setting (0 = low, 1 = normal, 2 = high)"))] pub gain_setting : u8 , # [doc = "Head angle"] # [cfg_attr (feature = "schemars" , schemars (description = "Head angle"))] pub angle : u16 , # [doc = "Acoustic transmission duration (1~1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic transmission duration (1~1000 us)"))] pub transmit_duration : u16 , # [doc = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [cfg_attr (feature = "schemars" , schemars (description = "Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"))] pub sample_period : u16 , # [doc = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."))] pub transmit_frequency : u16 , # [doc = "Number of samples per reflected signal (supported values: 200~1200)"] # [cfg_attr (feature = "schemars" , schemars (description = "Number of samples per reflected signal (supported values: 200~1200)"))] pub number_of_samples : u16 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub data : Vec < u8 > , } impl SerializePayload for DeviceDataStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . angle . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . sample_period . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_frequency . to_le_bytes ()) ; buffer . extend_from_slice (& self . number_of_samples . to_le_bytes ()) ; buffer . extend_from_slice (& self . data_length . to_le_bytes ()) ; for value in self . data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for DeviceDataStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode : payload [0usize] . into () , gain_setting : payload [1usize] . into () , angle : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , sample_period : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_frequency : u16 :: from_le_bytes (payload [8usize .. 8usize + 2usize] . try_into () . expect ("Wrong slice length")) , number_of_samples : u16 :: from_le_bytes (payload [10usize .. 10usize + 2usize] . try_into () . expect ("Wrong slice length")) , data_length : u16 :: from_le_bytes (payload [12usize .. 12usize + 2usize] . try_into () . expect ("Wrong slice length")) , data : payload [12usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for DeviceDataStruct { fn id () -> u16 { 2300u16 } fn name () -> & 'static str { "device_data" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] pub struct ResetStruct { # [doc = "0 = skip bootloader; 1 = run bootloader"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = skip bootloader; 1 = run bootloader"))] pub bootloader : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ResetStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . bootloader . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ResetStruct { fn deserialize (payload : & [u8]) -> Self { Self { bootloader : payload [0usize] . into () , reserved : <u8 as Into<_>>::into(payload [1usize]) , } } } impl MessageInfo for ResetStruct { fn id () -> u16 { 2600u16 } fn name () -> & 'static str { "reset" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "**NEW (v1.1.0)** Extended `transducer` message with auto-scan function. The sonar will automatically scan the region between `start_angle` and `end_angle` and send `auto_device_data` messages as soon as new data is available. Send a line break to stop scanning (and also begin the autobaudrate procedure). Alternatively, a `motor_off` message may be sent (but retries might be necessary on the half-duplex RS485 interface)."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `start_angle` \\[gradians\\] - Head angle to begin scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `stop_angle` \\[gradians\\] - Head angle to end scan sector for autoscan (0~399 = 0~360 degrees)."] # [doc = "* `num_steps` \\[gradians\\] - Number of 0.9 degree motor steps between pings for auto scan (1~10 = 0.9~9.0 degrees)"] # [doc = "* `delay` \\[milliseconds\\] - An additional delay between successive transmit pulses (0~100 ms). This may be necessary for some programs to avoid collisions on the RS485 USRT."] pub async fn auto_transmit (& self , mode : u8 , gain_setting : u8 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , start_angle : u16 , stop_angle : u16 , num_steps : u8 , delay : u8) -> Result < () , PingError > { let request = Messages :: AutoTransmit (AutoTransmitStruct { mode , gain_setting , transmit_duration , sample_period , transmit_frequency , number_of_samples , start_angle , stop_angle , num_steps , delay , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The sonar switches the current through the stepper motor windings off to save power. The sonar will send an ack message in response. The command timeout should be set to 50 msec. If the sonar is idle (not scanning) for more than 30 seconds then the motor current will automatically turn off. When the user sends any command that involves moving the transducer then the motor current is automatically re-enabled."] # [doc = "# Arguments"] pub async fn motor_off (& self ,) -> Result < () , PingError > { let request = Messages :: MotorOff (MotorOffStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The transducer will apply the commanded settings. The sonar will reply with a `device_data` message. If the `transmit` field is 0, the sonar will not transmit after locating the transducer, and the `data` field in the `device_data` message reply will be empty. If the `transmit` field is 1, the sonar will make an acoustic transmission after locating the transducer, and the resulting data will be uploaded in the `data` field of the `device_data` message reply. To allow for the worst case response time the command timeout should be set to 4000 msec."] # [doc = "# Arguments"] # [doc = "* `mode` - Operating mode (1 for Ping360)"] # [doc = "* `gain_setting` - Analog gain setting (0 = low, 1 = normal, 2 = high)"] # [doc = "* `angle` \\[gradians\\] - Head angle"] # [doc = "* `transmit_duration` \\[microseconds\\] - Acoustic transmission duration (1~1000 us)"] # [doc = "* `sample_period` \\[eicosapenta-nanoseconds\\] - Time interval between individual signal intensity samples in 25 ns increments (80 to 40000 == 2 to 1000 us)"] # [doc = "* `transmit_frequency` \\[kilohertz\\] - Acoustic operating frequency (500~1000 kHz). It is only practical to use say 650 to 850 kHz due to the narrow bandwidth of the acoustic receiver."] # [doc = "* `number_of_samples` \\[samples\\] - Number of samples per reflected signal (supported values: 200~1200)"] # [doc = "* `transmit` - 0 = do not transmit; 1 = transmit after the transducer has reached the specified angle"] # [doc = "* `reserved` - reserved"] pub async fn transducer (& self , mode : u8 , gain_setting : u8 , angle : u16 , transmit_duration : u16 , sample_period : u16 , transmit_frequency : u16 , number_of_samples : u16 , transmit : u8 , reserved : u8) -> Result < DeviceDataStruct , PingError > { let request = Messages :: Transducer (TransducerStruct { mode , gain_setting , angle , transmit_duration , sample_period , transmit_frequency , number_of_samples , transmit , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_message (receiver) . await } # [doc = "Change the device id"] # [doc = "# Arguments"] # [doc = "* `id` - Device ID (1-254). 0 and 255 are reserved."] # [doc = "* `reserved` - reserved"] pub async fn set_device_id (& self , id : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { id , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "**NEW (v1.1.0)** Extended version of `device_data` with `auto_transmit` information. The sensor emits this message when in `auto_transmit` mode."] pub async fn auto_device_data (& self) -> Result < AutoDeviceDataStruct , PingError > { self . request () . await } # [doc = "This message is used to communicate the current sonar state. If the data field is populated, the other fields indicate the sonar state when the data was captured. The time taken before the response to the command is sent depends on the difference between the last angle scanned and the new angle in the parameters as well as the number of samples and sample interval (range). To allow for the worst case reponse time the command timeout should be set to 4000 msec."] pub async fn device_data (& self) -> Result < DeviceDataStruct , PingError > { self . request () . await } # [doc = "Reset the sonar. The bootloader may run depending on the selection according to the `bootloader` payload field. When the bootloader runs, the external LED flashes at 5Hz. If the bootloader is not contacted within 5 seconds, it will run the current program. If there is no program, then the bootloader will wait forever for a connection. Note that if you issue a reset then you will have to close all your open comm ports and go back to issuing either a discovery message for UDP or go through the break sequence for serial comms before you can talk to the sonar again."] # [doc = "# Arguments"] # [doc = "* `bootloader` - 0 = skip bootloader; 1 = run bootloader"] # [doc = "* `reserved` - reserved"] pub async fn reset (& self , bootloader : u8 , reserved : u8) -> Result < () , PingError > { let request = Messages :: Reset (ResetStruct { bootloader , reserved , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: AutoTransmit (..) => "auto_transmit" , Messages :: MotorOff (..) => "motor_off" , Messages :: Transducer (..) => "transducer" , Messages :: SetDeviceId (..) => "set_device_id" , Messages :: AutoDeviceData (..) => "auto_device_data" , Messages :: DeviceData (..) => "device_data" , Messages :: Reset (..) => "reset" , } } fn message_id (& self) -> u16 { match self { Messages :: AutoTransmit (..) => 2602u16 , Messages :: MotorOff (..) => 2903u16 , Messages :: Transducer (..) => 2601u16 , Messages :: SetDeviceId (..) => 2000u16 , Messages :: AutoDeviceData (..) => 2301u16 , Messages :: DeviceData (..) => 2300u16 , Messages :: Reset (..) => 2600u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "auto_transmit" => Ok (2602u16) , "motor_off" => Ok (2903u16) , "transducer" => Ok (2601u16) , "set_device_id" => Ok (2000u16) , "auto_device_data" => Ok (2301u16) , "device_data" => Ok (2300u16) , "reset" => Ok (2600u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: AutoTransmit (content) => (content as & dyn SerializePayload) . serialize () , Messages :: MotorOff (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Transducer (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AutoDeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceData (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reset (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 2602u16 => Messages :: AutoTransmit (< AutoTransmitStruct as DeserializePayload > :: deserialize (payload)) , 2903u16 => Messages :: MotorOff (< MotorOffStruct as DeserializePayload > :: deserialize (payload)) , 2601u16 => Messages :: Transducer (< TransducerStruct as DeserializePayload > :: deserialize (payload)) , 2000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 2301u16 => Messages :: AutoDeviceData (< AutoDeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2300u16 => Messages :: DeviceData (< DeviceDataStruct as DeserializePayload > :: deserialize (payload)) , 2600u16 => Messages :: Reset (< ResetStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/bluebps.rs:1:26356
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ayload : & [u8]) -> Self { Self { goto_bootloader : payload [0usize] . into () , } } } impl MessageInfo for RebootStruct { fn id (...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetStreamRate (SetStreamRateStruct) , CellTimeout (CellTimeoutStruct) , CurrentTimeout (CurrentTimeoutStruct) , CurrentMax (CurrentMaxStruct) , TemperatureTimeout (TemperatureTimeoutStruct) , SetLpfSetting (SetLpfSettingStruct) , SetCellVoltageTimeout (SetCellVoltageTimeoutStruct) , SetCurrentMax (SetCurrentMaxStruct) , SetLpfSampleFrequency (SetLpfSampleFrequencyStruct) , SetTemperatureMax (SetTemperatureMaxStruct) , TemperatureMax (TemperatureMaxStruct) , Events (EventsStruct) , SetCurrentTimeout (SetCurrentTimeoutStruct) , SetTemperatureTimeout (SetTemperatureTimeoutStruct) , EraseFlash (EraseFlashStruct) , ResetDefaults (ResetDefaultsStruct) , Reboot (RebootStruct) , CellVoltageMin (CellVoltageMinStruct) , SetCellVoltageMinimum (SetCellVoltageMinimumStruct) , State (StateStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetStreamRate (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSampleFrequency (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Events (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: EraseFlash (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ResetDefaults (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reboot (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellVoltageMin (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageMinimum (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: State (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the frequency to automatically output state messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the frequency to automatically output state messages."] pub struct SetStreamRateStruct { # [doc = "Rate to stream `state` messages. 0~100000Hz"] # [cfg_attr (feature = "schemars" , schemars (description = "Rate to stream `state` messages. 0~100000Hz"))] pub rate : u32 , } impl SerializePayload for SetStreamRateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . rate . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetStreamRateStruct { fn deserialize (payload : & [u8]) -> Self { Self { rate : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetStreamRateStruct { fn id () -> u16 { 9006u16 } fn name () -> & 'static str { "set_stream_rate" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the undervoltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the undervoltage timeout"] pub struct CellTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CellTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellTimeoutStruct { fn id () -> u16 { 9101u16 } fn name () -> & 'static str { "cell_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-current timeout"] pub struct CurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentTimeoutStruct { fn id () -> u16 { 9103u16 } fn name () -> & 'static str { "current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "get the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "get the maximum allowed battery current"] pub struct CurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for CurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentMaxStruct { fn id () -> u16 { 9102u16 } fn name () -> & 'static str { "current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-temperature timeout"] pub struct TemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for TemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureTimeoutStruct { fn id () -> u16 { 9105u16 } fn name () -> & 'static str { "temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] pub struct SetLpfSettingStruct { # [doc = "0~999: x = 0~0.999"] # [cfg_attr (feature = "schemars" , schemars (description = "0~999: x = 0~0.999"))] pub setting : u16 , } impl SerializePayload for SetLpfSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { setting : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSettingStruct { fn id () -> u16 { 9008u16 } fn name () -> & 'static str { "set_lpf_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the under-voltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the under-voltage timeout"] pub struct SetCellVoltageTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCellVoltageTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageTimeoutStruct { fn id () -> u16 { 9001u16 } fn name () -> & 'static str { "set_cell_voltage_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery current"] pub struct SetCurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for SetCurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentMaxStruct { fn id () -> u16 { 9002u16 } fn name () -> & 'static str { "set_current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "the frequency to take adc samples and run the filter."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "the frequency to take adc samples and run the filter."] pub struct SetLpfSampleFrequencyStruct { # [doc = "sample frequency in Hz. 1~100000"] # [cfg_attr (feature = "schemars" , schemars (description = "sample frequency in Hz. 1~100000"))] pub sample_frequency : u32 , } impl SerializePayload for SetLpfSampleFrequencyStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . sample_frequency . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSampleFrequencyStruct { fn deserialize (payload : & [u8]) -> Self { Self { sample_frequency : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSampleFrequencyStruct { fn id () -> u16 { 9007u16 } fn name () -> & 'static str { "set_lpf_sample_frequency" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery temperature"] pub struct SetTemperatureMaxStruct { # [doc = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetTemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureMaxStruct { fn id () -> u16 { 9004u16 } fn name () -> & 'static str { "set_temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the maximum allowed battery temperature"] pub struct TemperatureMaxStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for TemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureMaxStruct { fn id () -> u16 { 9104u16 } fn name () -> & 'static str { "temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub struct EventsStruct { # [doc = "The number of under-voltage events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of under-voltage events"))] pub voltage : u16 , # [doc = "The number of over-current events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-current events"))] pub current : u16 , # [doc = "The number of over-temperature events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-temperature events"))] pub temperature : u16 , } impl SerializePayload for EventsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . current . to_le_bytes ()) ; buffer . extend_from_slice (& self . temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for EventsStruct { fn deserialize (payload : & [u8]) -> Self { Self { voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for EventsStruct { fn id () -> u16 { 9107u16 } fn name () -> & 'static str { "events" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-current timeout"] pub struct SetCurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentTimeoutStruct { fn id () -> u16 { 9003u16 } fn name () -> & 'static str { "set_current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-temperature timeout"] pub struct SetTemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetTemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureTimeoutStruct { fn id () -> u16 { 9005u16 } fn name () -> & 'static str { "set_temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] pub struct EraseFlashStruct { } impl SerializePayload for EraseFlashStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for EraseFlashStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for EraseFlashStruct { fn id () -> u16 { 9201u16 } fn name () -> & 'static str { "erase_flash" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset parameter configuration to default values."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset parameter configuration to default values."] pub struct ResetDefaultsStruct { } impl SerializePayload for ResetDefaultsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for ResetDefaultsStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for ResetDefaultsStruct { fn id () -> u16 { 9202u16 } fn name () -> & 'static str { "reset_defaults" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "reboot the system"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "reboot the system"] pub struct RebootStruct { # [doc = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"))] pub goto_bootloader : u8 , } impl SerializePayload for RebootStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . goto_bootloader . to_le_bytes ()) ; buffer } } impl DeserializePayload for RebootStruct { fn deserialize (payload : & [u8]) -> Self { Self { goto_bootloader : payload [0usize] . into () , } } } impl MessageInfo for RebootStruct { fn id () -> u16 { 9200u16 } fn name () -> & 'static str { "reboot" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the minimum allowed cell voltage"] pub struct CellVoltageMinStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for CellVoltageMinStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellVoltageMinStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellVoltageMinStruct { fn id () -> u16 { 9100u16 } fn name () -> & 'static str { "cell_voltage_min" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the minimum allowed cell voltage"] pub struct SetCellVoltageMinimumStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetCellVoltageMinimumStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageMinimumStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageMinimumStruct { fn id () -> u16 { 9000u16 } fn name () -> & 'static str { "set_cell_voltage_minimum" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the current state of the device"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the current state of the device"] pub struct StateStruct { # [doc = "The main battery voltage"] # [cfg_attr (feature = "schemars" , schemars (description = "The main battery voltage"))] pub battery_voltage : u16 , # [doc = "The current measurement"] # [cfg_attr (feature = "schemars" , schemars (description = "The current measurement"))] pub battery_current : u16 , # [doc = "The battery temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The battery temperature"))] pub battery_temperature : u16 , # [doc = "The cpu temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The cpu temperature"))] pub cpu_temperature : u16 , # [doc = "flags indicating if any of the configured limits are currently exceeded"] # [cfg_attr (feature = "schemars" , schemars (description = "flags indicating if any of the configured limits are currently exceeded"))] pub flags : u8 , # [doc = "Array containing cell voltages"] # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages_length : u8 , # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages : Vec < u16 > , } impl SerializePayload for StateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . battery_voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_current . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . cpu_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . flags . to_le_bytes ()) ; buffer . extend_from_slice (& self . cell_voltages_length . to_le_bytes ()) ; for value in self . cell_voltages . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for StateStruct { fn deserialize (payload : & [u8]) -> Self { Self { battery_voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , cpu_temperature : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , flags : payload [8usize] . into () , cell_voltages_length : u8 :: from_le_bytes (payload [9usize .. 9usize + 1usize] . try_into () . expect ("Wrong slice length")) , cell_voltages : payload [9usize .. payload . len ()] . chunks_exact (2usize) . into_iter () . map (| a | u16 :: from_le_bytes ((* a) . try_into () . expect ("Wrong slice length"))) . collect :: < Vec < u16 >> () , } } } impl MessageInfo for StateStruct { fn id () -> u16 { 9106u16 } fn name () -> & 'static str { "state" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the frequency to automatically output state messages."] # [doc = "# Arguments"] # [doc = "* `rate` \\[Hz\\] - Rate to stream `state` messages. 0~100000Hz"] pub async fn set_stream_rate (& self , rate : u32) -> Result < () , PingError > { let request = Messages :: SetStreamRate (SetStreamRateStruct { rate , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetStreamRateStruct :: id ()) . await } # [doc = "Get the undervoltage timeout"] pub async fn cell_timeout (& self) -> Result < CellTimeoutStruct , PingError > { self . request () . await } # [doc = "Get the over-current timeout"] pub async fn current_timeout (& self) -> Result < CurrentTimeoutStruct , PingError > { self . request () . await } # [doc = "get the maximum allowed battery current"] pub async fn current_max (& self) -> Result < CurrentMaxStruct , PingError > { self . request () . await } # [doc = "Get the over-temperature timeout"] pub async fn temperature_timeout (& self) -> Result < TemperatureTimeoutStruct , PingError > { self . request () . await } # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] # [doc = "# Arguments"] # [doc = "* `setting` - 0~999: x = 0~0.999"] pub async fn set_lpf_setting (& self , setting : u16) -> Result < () , PingError > { let request = Messages :: SetLpfSetting (SetLpfSettingStruct { setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSettingStruct :: id ()) . await } # [doc = "Set the under-voltage timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_cell_voltage_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageTimeout (SetCellVoltageTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageTimeoutStruct :: id ()) . await } # [doc = "Set the maximum allowed battery current"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centiampere\\] - The maximum allowed battery current 0~20000 = 0~200A"] pub async fn set_current_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentMax (SetCurrentMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentMaxStruct :: id ()) . await } # [doc = "the frequency to take adc samples and run the filter."] # [doc = "# Arguments"] # [doc = "* `sample_frequency` - sample frequency in Hz. 1~100000"] pub async fn set_lpf_sample_frequency (& self , sample_frequency : u32) -> Result < () , PingError > { let request = Messages :: SetLpfSampleFrequency (SetLpfSampleFrequencyStruct { sample_frequency , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSampleFrequencyStruct :: id ()) . await } # [doc = "Set the maximum allowed battery temperature"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centidegrees Centigrade\\] - The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] pub async fn set_temperature_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureMax (SetTemperatureMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureMaxStruct :: id ()) . await } # [doc = "Get the maximum allowed battery temperature"] pub async fn temperature_max (& self) -> Result < TemperatureMaxStruct , PingError > { self . request () . await } # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub async fn events (& self) -> Result < EventsStruct , PingError > { self . request () . await } # [doc = "Set the over-current timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_current_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentTimeout (SetCurrentTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentTimeoutStruct :: id ()) . await } # [doc = "Set the over-temperature timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_temperature_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureTimeout (SetTemperatureTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureTimeoutStruct :: id ()) . await } # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] # [doc = "# Arguments"] pub async fn erase_flash (& self ,) -> Result < () , PingError > { let request = Messages :: EraseFlash (EraseFlashStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Reset parameter configuration to default values."] # [doc = "# Arguments"] pub async fn reset_defaults (& self ,) -> Result < () , PingError > { let request = Messages :: ResetDefaults (ResetDefaultsStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "reboot the system"] # [doc = "# Arguments"] # [doc = "* `goto_bootloader` - 0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] pub async fn reboot (& self , goto_bootloader : u8) -> Result < () , PingError > { let request = Messages :: Reboot (RebootStruct { goto_bootloader , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Get the minimum allowed cell voltage"] pub async fn cell_voltage_min (& self) -> Result < CellVoltageMinStruct , PingError > { self . request () . await } # [doc = "Set the minimum allowed cell voltage"] # [doc = "# Arguments"] # [doc = "* `limit` \\[millivolt\\] - The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] pub async fn set_cell_voltage_minimum (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageMinimum (SetCellVoltageMinimumStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageMinimumStruct :: id ()) . await } # [doc = "Get the current state of the device"] pub async fn state (& self) -> Result < StateStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetStreamRate (..) => "set_stream_rate" , Messages :: CellTimeout (..) => "cell_timeout" , Messages :: CurrentTimeout (..) => "current_timeout" , Messages :: CurrentMax (..) => "current_max" , Messages :: TemperatureTimeout (..) => "temperature_timeout" , Messages :: SetLpfSetting (..) => "set_lpf_setting" , Messages :: SetCellVoltageTimeout (..) => "set_cell_voltage_timeout" , Messages :: SetCurrentMax (..) => "set_current_max" , Messages :: SetLpfSampleFrequency (..) => "set_lpf_sample_frequency" , Messages :: SetTemperatureMax (..) => "set_temperature_max" , Messages :: TemperatureMax (..) => "temperature_max" , Messages :: Events (..) => "events" , Messages :: SetCurrentTimeout (..) => "set_current_timeout" , Messages :: SetTemperatureTimeout (..) => "set_temperature_timeout" , Messages :: EraseFlash (..) => "erase_flash" , Messages :: ResetDefaults (..) => "reset_defaults" , Messages :: Reboot (..) => "reboot" , Messages :: CellVoltageMin (..) => "cell_voltage_min" , Messages :: SetCellVoltageMinimum (..) => "set_cell_voltage_minimum" , Messages :: State (..) => "state" , } } fn message_id (& self) -> u16 { match self { Messages :: SetStreamRate (..) => 9006u16 , Messages :: CellTimeout (..) => 9101u16 , Messages :: CurrentTimeout (..) => 9103u16 , Messages :: CurrentMax (..) => 9102u16 , Messages :: TemperatureTimeout (..) => 9105u16 , Messages :: SetLpfSetting (..) => 9008u16 , Messages :: SetCellVoltageTimeout (..) => 9001u16 , Messages :: SetCurrentMax (..) => 9002u16 , Messages :: SetLpfSampleFrequency (..) => 9007u16 , Messages :: SetTemperatureMax (..) => 9004u16 , Messages :: TemperatureMax (..) => 9104u16 , Messages :: Events (..) => 9107u16 , Messages :: SetCurrentTimeout (..) => 9003u16 , Messages :: SetTemperatureTimeout (..) => 9005u16 , Messages :: EraseFlash (..) => 9201u16 , Messages :: ResetDefaults (..) => 9202u16 , Messages :: Reboot (..) => 9200u16 , Messages :: CellVoltageMin (..) => 9100u16 , Messages :: SetCellVoltageMinimum (..) => 9000u16 , Messages :: State (..) => 9106u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_stream_rate" => Ok (9006u16) , "cell_timeout" => Ok (9101u16) , "current_timeout" => Ok (9103u16) , "current_max" => Ok (9102u16) , "temperature_timeout" => Ok (9105u16) , "set_lpf_setting" => Ok (9008u16) , "set_cell_voltage_timeout" => Ok (9001u16) , "set_current_max" => Ok (9002u16) , "set_lpf_sample_frequency" => Ok (9007u16) , "set_temperature_max" => Ok (9004u16) , "temperature_max" => Ok (9104u16) , "events" => Ok (9107u16) , "set_current_timeout" => Ok (9003u16) , "set_temperature_timeout" => Ok (9005u16) , "erase_flash" => Ok (9201u16) , "reset_defaults" => Ok (9202u16) , "reboot" => Ok (9200u16) , "cell_voltage_min" => Ok (9100u16) , "set_cell_voltage_minimum" => Ok (9000u16) , "state" => Ok (9106u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetStreamRate (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSampleFrequency (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Events (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: EraseFlash (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ResetDefaults (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reboot (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellVoltageMin (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageMinimum (content) => (content as & dyn SerializePayload) . serialize () , Messages :: State (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 9006u16 => Messages :: SetStreamRate (< SetStreamRateStruct as DeserializePayload > :: deserialize (payload)) , 9101u16 => Messages :: CellTimeout (< CellTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9103u16 => Messages :: CurrentTimeout (< CurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9102u16 => Messages :: CurrentMax (< CurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9105u16 => Messages :: TemperatureTimeout (< TemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9008u16 => Messages :: SetLpfSetting (< SetLpfSettingStruct as DeserializePayload > :: deserialize (payload)) , 9001u16 => Messages :: SetCellVoltageTimeout (< SetCellVoltageTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9002u16 => Messages :: SetCurrentMax (< SetCurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9007u16 => Messages :: SetLpfSampleFrequency (< SetLpfSampleFrequencyStruct as DeserializePayload > :: deserialize (payload)) , 9004u16 => Messages :: SetTemperatureMax (< SetTemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9104u16 => Messages :: TemperatureMax (< TemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9107u16 => Messages :: Events (< EventsStruct as DeserializePayload > :: deserialize (payload)) , 9003u16 => Messages :: SetCurrentTimeout (< SetCurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9005u16 => Messages :: SetTemperatureTimeout (< SetTemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9201u16 => Messages :: EraseFlash (< EraseFlashStruct as DeserializePayload > :: deserialize (payload)) , 9202u16 => Messages :: ResetDefaults (< ResetDefaultsStruct as DeserializePayload > :: deserialize (payload)) , 9200u16 => Messages :: Reboot (< RebootStruct as DeserializePayload > :: deserialize (payload)) , 9100u16 => Messages :: CellVoltageMin (< CellVoltageMinStruct as DeserializePayload > :: deserialize (payload)) , 9000u16 => Messages :: SetCellVoltageMinimum (< SetCellVoltageMinimumStruct as DeserializePayload > :: deserialize (payload)) , 9106u16 => Messages :: State (< StateStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetStreamRate (SetStreamRateStruct) , CellTimeout (CellTimeoutStruct) , CurrentTimeout (CurrentTimeoutStruct) , CurrentMax (CurrentMaxStruct) , TemperatureTimeout (TemperatureTimeoutStruct) , SetLpfSetting (SetLpfSettingStruct) , SetCellVoltageTimeout (SetCellVoltageTimeoutStruct) , SetCurrentMax (SetCurrentMaxStruct) , SetLpfSampleFrequency (SetLpfSampleFrequencyStruct) , SetTemperatureMax (SetTemperatureMaxStruct) , TemperatureMax (TemperatureMaxStruct) , Events (EventsStruct) , SetCurrentTimeout (SetCurrentTimeoutStruct) , SetTemperatureTimeout (SetTemperatureTimeoutStruct) , EraseFlash (EraseFlashStruct) , ResetDefaults (ResetDefaultsStruct) , Reboot (RebootStruct) , CellVoltageMin (CellVoltageMinStruct) , SetCellVoltageMinimum (SetCellVoltageMinimumStruct) , State (StateStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetStreamRate (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSampleFrequency (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Events (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: EraseFlash (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ResetDefaults (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reboot (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellVoltageMin (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageMinimum (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: State (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the frequency to automatically output state messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the frequency to automatically output state messages."] pub struct SetStreamRateStruct { # [doc = "Rate to stream `state` messages. 0~100000Hz"] # [cfg_attr (feature = "schemars" , schemars (description = "Rate to stream `state` messages. 0~100000Hz"))] pub rate : u32 , } impl SerializePayload for SetStreamRateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . rate . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetStreamRateStruct { fn deserialize (payload : & [u8]) -> Self { Self { rate : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetStreamRateStruct { fn id () -> u16 { 9006u16 } fn name () -> & 'static str { "set_stream_rate" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the undervoltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the undervoltage timeout"] pub struct CellTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CellTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellTimeoutStruct { fn id () -> u16 { 9101u16 } fn name () -> & 'static str { "cell_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-current timeout"] pub struct CurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentTimeoutStruct { fn id () -> u16 { 9103u16 } fn name () -> & 'static str { "current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "get the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "get the maximum allowed battery current"] pub struct CurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for CurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentMaxStruct { fn id () -> u16 { 9102u16 } fn name () -> & 'static str { "current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-temperature timeout"] pub struct TemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for TemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureTimeoutStruct { fn id () -> u16 { 9105u16 } fn name () -> & 'static str { "temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] pub struct SetLpfSettingStruct { # [doc = "0~999: x = 0~0.999"] # [cfg_attr (feature = "schemars" , schemars (description = "0~999: x = 0~0.999"))] pub setting : u16 , } impl SerializePayload for SetLpfSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { setting : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSettingStruct { fn id () -> u16 { 9008u16 } fn name () -> & 'static str { "set_lpf_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the under-voltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the under-voltage timeout"] pub struct SetCellVoltageTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCellVoltageTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageTimeoutStruct { fn id () -> u16 { 9001u16 } fn name () -> & 'static str { "set_cell_voltage_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery current"] pub struct SetCurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for SetCurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentMaxStruct { fn id () -> u16 { 9002u16 } fn name () -> & 'static str { "set_current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "the frequency to take adc samples and run the filter."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "the frequency to take adc samples and run the filter."] pub struct SetLpfSampleFrequencyStruct { # [doc = "sample frequency in Hz. 1~100000"] # [cfg_attr (feature = "schemars" , schemars (description = "sample frequency in Hz. 1~100000"))] pub sample_frequency : u32 , } impl SerializePayload for SetLpfSampleFrequencyStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . sample_frequency . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSampleFrequencyStruct { fn deserialize (payload : & [u8]) -> Self { Self { sample_frequency : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSampleFrequencyStruct { fn id () -> u16 { 9007u16 } fn name () -> & 'static str { "set_lpf_sample_frequency" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery temperature"] pub struct SetTemperatureMaxStruct { # [doc = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetTemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureMaxStruct { fn id () -> u16 { 9004u16 } fn name () -> & 'static str { "set_temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the maximum allowed battery temperature"] pub struct TemperatureMaxStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for TemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureMaxStruct { fn id () -> u16 { 9104u16 } fn name () -> & 'static str { "temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub struct EventsStruct { # [doc = "The number of under-voltage events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of under-voltage events"))] pub voltage : u16 , # [doc = "The number of over-current events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-current events"))] pub current : u16 , # [doc = "The number of over-temperature events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-temperature events"))] pub temperature : u16 , } impl SerializePayload for EventsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . current . to_le_bytes ()) ; buffer . extend_from_slice (& self . temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for EventsStruct { fn deserialize (payload : & [u8]) -> Self { Self { voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for EventsStruct { fn id () -> u16 { 9107u16 } fn name () -> & 'static str { "events" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-current timeout"] pub struct SetCurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentTimeoutStruct { fn id () -> u16 { 9003u16 } fn name () -> & 'static str { "set_current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-temperature timeout"] pub struct SetTemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetTemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureTimeoutStruct { fn id () -> u16 { 9005u16 } fn name () -> & 'static str { "set_temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] pub struct EraseFlashStruct { } impl SerializePayload for EraseFlashStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for EraseFlashStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for EraseFlashStruct { fn id () -> u16 { 9201u16 } fn name () -> & 'static str { "erase_flash" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset parameter configuration to default values."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset parameter configuration to default values."] pub struct ResetDefaultsStruct { } impl SerializePayload for ResetDefaultsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for ResetDefaultsStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for ResetDefaultsStruct { fn id () -> u16 { 9202u16 } fn name () -> & 'static str { "reset_defaults" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "reboot the system"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "reboot the system"] pub struct RebootStruct { # [doc = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"))] pub goto_bootloader : u8 , } impl SerializePayload for RebootStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . goto_bootloader . to_le_bytes ()) ; buffer } } impl DeserializePayload for RebootStruct { fn deserialize (payload : & [u8]) -> Self { Self { goto_bootloader : payload [0usize] , } } } impl MessageInfo for RebootStruct { fn id () -> u16 { 9200u16 } fn name () -> & 'static str { "reboot" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the minimum allowed cell voltage"] pub struct CellVoltageMinStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for CellVoltageMinStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellVoltageMinStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellVoltageMinStruct { fn id () -> u16 { 9100u16 } fn name () -> & 'static str { "cell_voltage_min" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the minimum allowed cell voltage"] pub struct SetCellVoltageMinimumStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetCellVoltageMinimumStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageMinimumStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageMinimumStruct { fn id () -> u16 { 9000u16 } fn name () -> & 'static str { "set_cell_voltage_minimum" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the current state of the device"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the current state of the device"] pub struct StateStruct { # [doc = "The main battery voltage"] # [cfg_attr (feature = "schemars" , schemars (description = "The main battery voltage"))] pub battery_voltage : u16 , # [doc = "The current measurement"] # [cfg_attr (feature = "schemars" , schemars (description = "The current measurement"))] pub battery_current : u16 , # [doc = "The battery temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The battery temperature"))] pub battery_temperature : u16 , # [doc = "The cpu temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The cpu temperature"))] pub cpu_temperature : u16 , # [doc = "flags indicating if any of the configured limits are currently exceeded"] # [cfg_attr (feature = "schemars" , schemars (description = "flags indicating if any of the configured limits are currently exceeded"))] pub flags : u8 , # [doc = "Array containing cell voltages"] # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages_length : u8 , # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages : Vec < u16 > , } impl SerializePayload for StateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . battery_voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_current . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . cpu_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . flags . to_le_bytes ()) ; buffer . extend_from_slice (& self . cell_voltages_length . to_le_bytes ()) ; for value in self . cell_voltages . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for StateStruct { fn deserialize (payload : & [u8]) -> Self { Self { battery_voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , cpu_temperature : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , flags : payload [8usize] . into () , cell_voltages_length : u8 :: from_le_bytes (payload [9usize .. 9usize + 1usize] . try_into () . expect ("Wrong slice length")) , cell_voltages : payload [9usize .. payload . len ()] . chunks_exact (2usize) . into_iter () . map (| a | u16 :: from_le_bytes ((* a) . try_into () . expect ("Wrong slice length"))) . collect :: < Vec < u16 >> () , } } } impl MessageInfo for StateStruct { fn id () -> u16 { 9106u16 } fn name () -> & 'static str { "state" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the frequency to automatically output state messages."] # [doc = "# Arguments"] # [doc = "* `rate` \\[Hz\\] - Rate to stream `state` messages. 0~100000Hz"] pub async fn set_stream_rate (& self , rate : u32) -> Result < () , PingError > { let request = Messages :: SetStreamRate (SetStreamRateStruct { rate , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetStreamRateStruct :: id ()) . await } # [doc = "Get the undervoltage timeout"] pub async fn cell_timeout (& self) -> Result < CellTimeoutStruct , PingError > { self . request () . await } # [doc = "Get the over-current timeout"] pub async fn current_timeout (& self) -> Result < CurrentTimeoutStruct , PingError > { self . request () . await } # [doc = "get the maximum allowed battery current"] pub async fn current_max (& self) -> Result < CurrentMaxStruct , PingError > { self . request () . await } # [doc = "Get the over-temperature timeout"] pub async fn temperature_timeout (& self) -> Result < TemperatureTimeoutStruct , PingError > { self . request () . await } # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] # [doc = "# Arguments"] # [doc = "* `setting` - 0~999: x = 0~0.999"] pub async fn set_lpf_setting (& self , setting : u16) -> Result < () , PingError > { let request = Messages :: SetLpfSetting (SetLpfSettingStruct { setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSettingStruct :: id ()) . await } # [doc = "Set the under-voltage timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_cell_voltage_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageTimeout (SetCellVoltageTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageTimeoutStruct :: id ()) . await } # [doc = "Set the maximum allowed battery current"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centiampere\\] - The maximum allowed battery current 0~20000 = 0~200A"] pub async fn set_current_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentMax (SetCurrentMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentMaxStruct :: id ()) . await } # [doc = "the frequency to take adc samples and run the filter."] # [doc = "# Arguments"] # [doc = "* `sample_frequency` - sample frequency in Hz. 1~100000"] pub async fn set_lpf_sample_frequency (& self , sample_frequency : u32) -> Result < () , PingError > { let request = Messages :: SetLpfSampleFrequency (SetLpfSampleFrequencyStruct { sample_frequency , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSampleFrequencyStruct :: id ()) . await } # [doc = "Set the maximum allowed battery temperature"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centidegrees Centigrade\\] - The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] pub async fn set_temperature_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureMax (SetTemperatureMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureMaxStruct :: id ()) . await } # [doc = "Get the maximum allowed battery temperature"] pub async fn temperature_max (& self) -> Result < TemperatureMaxStruct , PingError > { self . request () . await } # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub async fn events (& self) -> Result < EventsStruct , PingError > { self . request () . await } # [doc = "Set the over-current timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_current_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentTimeout (SetCurrentTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentTimeoutStruct :: id ()) . await } # [doc = "Set the over-temperature timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_temperature_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureTimeout (SetTemperatureTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureTimeoutStruct :: id ()) . await } # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] # [doc = "# Arguments"] pub async fn erase_flash (& self ,) -> Result < () , PingError > { let request = Messages :: EraseFlash (EraseFlashStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Reset parameter configuration to default values."] # [doc = "# Arguments"] pub async fn reset_defaults (& self ,) -> Result < () , PingError > { let request = Messages :: ResetDefaults (ResetDefaultsStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "reboot the system"] # [doc = "# Arguments"] # [doc = "* `goto_bootloader` - 0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] pub async fn reboot (& self , goto_bootloader : u8) -> Result < () , PingError > { let request = Messages :: Reboot (RebootStruct { goto_bootloader , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Get the minimum allowed cell voltage"] pub async fn cell_voltage_min (& self) -> Result < CellVoltageMinStruct , PingError > { self . request () . await } # [doc = "Set the minimum allowed cell voltage"] # [doc = "# Arguments"] # [doc = "* `limit` \\[millivolt\\] - The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] pub async fn set_cell_voltage_minimum (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageMinimum (SetCellVoltageMinimumStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageMinimumStruct :: id ()) . await } # [doc = "Get the current state of the device"] pub async fn state (& self) -> Result < StateStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetStreamRate (..) => "set_stream_rate" , Messages :: CellTimeout (..) => "cell_timeout" , Messages :: CurrentTimeout (..) => "current_timeout" , Messages :: CurrentMax (..) => "current_max" , Messages :: TemperatureTimeout (..) => "temperature_timeout" , Messages :: SetLpfSetting (..) => "set_lpf_setting" , Messages :: SetCellVoltageTimeout (..) => "set_cell_voltage_timeout" , Messages :: SetCurrentMax (..) => "set_current_max" , Messages :: SetLpfSampleFrequency (..) => "set_lpf_sample_frequency" , Messages :: SetTemperatureMax (..) => "set_temperature_max" , Messages :: TemperatureMax (..) => "temperature_max" , Messages :: Events (..) => "events" , Messages :: SetCurrentTimeout (..) => "set_current_timeout" , Messages :: SetTemperatureTimeout (..) => "set_temperature_timeout" , Messages :: EraseFlash (..) => "erase_flash" , Messages :: ResetDefaults (..) => "reset_defaults" , Messages :: Reboot (..) => "reboot" , Messages :: CellVoltageMin (..) => "cell_voltage_min" , Messages :: SetCellVoltageMinimum (..) => "set_cell_voltage_minimum" , Messages :: State (..) => "state" , } } fn message_id (& self) -> u16 { match self { Messages :: SetStreamRate (..) => 9006u16 , Messages :: CellTimeout (..) => 9101u16 , Messages :: CurrentTimeout (..) => 9103u16 , Messages :: CurrentMax (..) => 9102u16 , Messages :: TemperatureTimeout (..) => 9105u16 , Messages :: SetLpfSetting (..) => 9008u16 , Messages :: SetCellVoltageTimeout (..) => 9001u16 , Messages :: SetCurrentMax (..) => 9002u16 , Messages :: SetLpfSampleFrequency (..) => 9007u16 , Messages :: SetTemperatureMax (..) => 9004u16 , Messages :: TemperatureMax (..) => 9104u16 , Messages :: Events (..) => 9107u16 , Messages :: SetCurrentTimeout (..) => 9003u16 , Messages :: SetTemperatureTimeout (..) => 9005u16 , Messages :: EraseFlash (..) => 9201u16 , Messages :: ResetDefaults (..) => 9202u16 , Messages :: Reboot (..) => 9200u16 , Messages :: CellVoltageMin (..) => 9100u16 , Messages :: SetCellVoltageMinimum (..) => 9000u16 , Messages :: State (..) => 9106u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_stream_rate" => Ok (9006u16) , "cell_timeout" => Ok (9101u16) , "current_timeout" => Ok (9103u16) , "current_max" => Ok (9102u16) , "temperature_timeout" => Ok (9105u16) , "set_lpf_setting" => Ok (9008u16) , "set_cell_voltage_timeout" => Ok (9001u16) , "set_current_max" => Ok (9002u16) , "set_lpf_sample_frequency" => Ok (9007u16) , "set_temperature_max" => Ok (9004u16) , "temperature_max" => Ok (9104u16) , "events" => Ok (9107u16) , "set_current_timeout" => Ok (9003u16) , "set_temperature_timeout" => Ok (9005u16) , "erase_flash" => Ok (9201u16) , "reset_defaults" => Ok (9202u16) , "reboot" => Ok (9200u16) , "cell_voltage_min" => Ok (9100u16) , "set_cell_voltage_minimum" => Ok (9000u16) , "state" => Ok (9106u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetStreamRate (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSampleFrequency (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Events (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: EraseFlash (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ResetDefaults (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reboot (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellVoltageMin (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageMinimum (content) => (content as & dyn SerializePayload) . serialize () , Messages :: State (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 9006u16 => Messages :: SetStreamRate (< SetStreamRateStruct as DeserializePayload > :: deserialize (payload)) , 9101u16 => Messages :: CellTimeout (< CellTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9103u16 => Messages :: CurrentTimeout (< CurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9102u16 => Messages :: CurrentMax (< CurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9105u16 => Messages :: TemperatureTimeout (< TemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9008u16 => Messages :: SetLpfSetting (< SetLpfSettingStruct as DeserializePayload > :: deserialize (payload)) , 9001u16 => Messages :: SetCellVoltageTimeout (< SetCellVoltageTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9002u16 => Messages :: SetCurrentMax (< SetCurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9007u16 => Messages :: SetLpfSampleFrequency (< SetLpfSampleFrequencyStruct as DeserializePayload > :: deserialize (payload)) , 9004u16 => Messages :: SetTemperatureMax (< SetTemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9104u16 => Messages :: TemperatureMax (< TemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9107u16 => Messages :: Events (< EventsStruct as DeserializePayload > :: deserialize (payload)) , 9003u16 => Messages :: SetCurrentTimeout (< SetCurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9005u16 => Messages :: SetTemperatureTimeout (< SetTemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9201u16 => Messages :: EraseFlash (< EraseFlashStruct as DeserializePayload > :: deserialize (payload)) , 9202u16 => Messages :: ResetDefaults (< ResetDefaultsStruct as DeserializePayload > :: deserialize (payload)) , 9200u16 => Messages :: Reboot (< RebootStruct as DeserializePayload > :: deserialize (payload)) , 9100u16 => Messages :: CellVoltageMin (< CellVoltageMinStruct as DeserializePayload > :: deserialize (payload)) , 9000u16 => Messages :: SetCellVoltageMinimum (< SetCellVoltageMinimumStruct as DeserializePayload > :: deserialize (payload)) , 9106u16 => Messages :: State (< StateStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetStreamRate (SetStreamRateStruct) , CellTimeout (CellTimeoutStruct) , CurrentTimeout (CurrentTimeoutStruct) , CurrentMax (CurrentMaxStruct) , TemperatureTimeout (TemperatureTimeoutStruct) , SetLpfSetting (SetLpfSettingStruct) , SetCellVoltageTimeout (SetCellVoltageTimeoutStruct) , SetCurrentMax (SetCurrentMaxStruct) , SetLpfSampleFrequency (SetLpfSampleFrequencyStruct) , SetTemperatureMax (SetTemperatureMaxStruct) , TemperatureMax (TemperatureMaxStruct) , Events (EventsStruct) , SetCurrentTimeout (SetCurrentTimeoutStruct) , SetTemperatureTimeout (SetTemperatureTimeoutStruct) , EraseFlash (EraseFlashStruct) , ResetDefaults (ResetDefaultsStruct) , Reboot (RebootStruct) , CellVoltageMin (CellVoltageMinStruct) , SetCellVoltageMinimum (SetCellVoltageMinimumStruct) , State (StateStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetStreamRate (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSampleFrequency (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Events (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: EraseFlash (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ResetDefaults (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reboot (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellVoltageMin (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageMinimum (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: State (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the frequency to automatically output state messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the frequency to automatically output state messages."] pub struct SetStreamRateStruct { # [doc = "Rate to stream `state` messages. 0~100000Hz"] # [cfg_attr (feature = "schemars" , schemars (description = "Rate to stream `state` messages. 0~100000Hz"))] pub rate : u32 , } impl SerializePayload for SetStreamRateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . rate . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetStreamRateStruct { fn deserialize (payload : & [u8]) -> Self { Self { rate : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetStreamRateStruct { fn id () -> u16 { 9006u16 } fn name () -> & 'static str { "set_stream_rate" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the undervoltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the undervoltage timeout"] pub struct CellTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CellTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellTimeoutStruct { fn id () -> u16 { 9101u16 } fn name () -> & 'static str { "cell_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-current timeout"] pub struct CurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentTimeoutStruct { fn id () -> u16 { 9103u16 } fn name () -> & 'static str { "current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "get the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "get the maximum allowed battery current"] pub struct CurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for CurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentMaxStruct { fn id () -> u16 { 9102u16 } fn name () -> & 'static str { "current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-temperature timeout"] pub struct TemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for TemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureTimeoutStruct { fn id () -> u16 { 9105u16 } fn name () -> & 'static str { "temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] pub struct SetLpfSettingStruct { # [doc = "0~999: x = 0~0.999"] # [cfg_attr (feature = "schemars" , schemars (description = "0~999: x = 0~0.999"))] pub setting : u16 , } impl SerializePayload for SetLpfSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { setting : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSettingStruct { fn id () -> u16 { 9008u16 } fn name () -> & 'static str { "set_lpf_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the under-voltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the under-voltage timeout"] pub struct SetCellVoltageTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCellVoltageTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageTimeoutStruct { fn id () -> u16 { 9001u16 } fn name () -> & 'static str { "set_cell_voltage_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery current"] pub struct SetCurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for SetCurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentMaxStruct { fn id () -> u16 { 9002u16 } fn name () -> & 'static str { "set_current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "the frequency to take adc samples and run the filter."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "the frequency to take adc samples and run the filter."] pub struct SetLpfSampleFrequencyStruct { # [doc = "sample frequency in Hz. 1~100000"] # [cfg_attr (feature = "schemars" , schemars (description = "sample frequency in Hz. 1~100000"))] pub sample_frequency : u32 , } impl SerializePayload for SetLpfSampleFrequencyStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . sample_frequency . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSampleFrequencyStruct { fn deserialize (payload : & [u8]) -> Self { Self { sample_frequency : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSampleFrequencyStruct { fn id () -> u16 { 9007u16 } fn name () -> & 'static str { "set_lpf_sample_frequency" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery temperature"] pub struct SetTemperatureMaxStruct { # [doc = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetTemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureMaxStruct { fn id () -> u16 { 9004u16 } fn name () -> & 'static str { "set_temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the maximum allowed battery temperature"] pub struct TemperatureMaxStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for TemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureMaxStruct { fn id () -> u16 { 9104u16 } fn name () -> & 'static str { "temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub struct EventsStruct { # [doc = "The number of under-voltage events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of under-voltage events"))] pub voltage : u16 , # [doc = "The number of over-current events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-current events"))] pub current : u16 , # [doc = "The number of over-temperature events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-temperature events"))] pub temperature : u16 , } impl SerializePayload for EventsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . current . to_le_bytes ()) ; buffer . extend_from_slice (& self . temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for EventsStruct { fn deserialize (payload : & [u8]) -> Self { Self { voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for EventsStruct { fn id () -> u16 { 9107u16 } fn name () -> & 'static str { "events" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-current timeout"] pub struct SetCurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentTimeoutStruct { fn id () -> u16 { 9003u16 } fn name () -> & 'static str { "set_current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-temperature timeout"] pub struct SetTemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetTemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureTimeoutStruct { fn id () -> u16 { 9005u16 } fn name () -> & 'static str { "set_temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] pub struct EraseFlashStruct { } impl SerializePayload for EraseFlashStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for EraseFlashStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for EraseFlashStruct { fn id () -> u16 { 9201u16 } fn name () -> & 'static str { "erase_flash" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset parameter configuration to default values."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset parameter configuration to default values."] pub struct ResetDefaultsStruct { } impl SerializePayload for ResetDefaultsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for ResetDefaultsStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for ResetDefaultsStruct { fn id () -> u16 { 9202u16 } fn name () -> & 'static str { "reset_defaults" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "reboot the system"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "reboot the system"] pub struct RebootStruct { # [doc = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"))] pub goto_bootloader : u8 , } impl SerializePayload for RebootStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . goto_bootloader . to_le_bytes ()) ; buffer } } impl DeserializePayload for RebootStruct { fn deserialize (payload : & [u8]) -> Self { Self { goto_bootloader : payload [0usize] . into () , } } } impl MessageInfo for RebootStruct { fn id () -> u16 { 9200u16 } fn name () -> & 'static str { "reboot" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the minimum allowed cell voltage"] pub struct CellVoltageMinStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for CellVoltageMinStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellVoltageMinStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellVoltageMinStruct { fn id () -> u16 { 9100u16 } fn name () -> & 'static str { "cell_voltage_min" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the minimum allowed cell voltage"] pub struct SetCellVoltageMinimumStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetCellVoltageMinimumStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageMinimumStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageMinimumStruct { fn id () -> u16 { 9000u16 } fn name () -> & 'static str { "set_cell_voltage_minimum" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the current state of the device"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the current state of the device"] pub struct StateStruct { # [doc = "The main battery voltage"] # [cfg_attr (feature = "schemars" , schemars (description = "The main battery voltage"))] pub battery_voltage : u16 , # [doc = "The current measurement"] # [cfg_attr (feature = "schemars" , schemars (description = "The current measurement"))] pub battery_current : u16 , # [doc = "The battery temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The battery temperature"))] pub battery_temperature : u16 , # [doc = "The cpu temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The cpu temperature"))] pub cpu_temperature : u16 , # [doc = "flags indicating if any of the configured limits are currently exceeded"] # [cfg_attr (feature = "schemars" , schemars (description = "flags indicating if any of the configured limits are currently exceeded"))] pub flags : u8 , # [doc = "Array containing cell voltages"] # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages_length : u8 , # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages : Vec < u16 > , } impl SerializePayload for StateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . battery_voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_current . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . cpu_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . flags . to_le_bytes ()) ; buffer . extend_from_slice (& self . cell_voltages_length . to_le_bytes ()) ; for value in self . cell_voltages . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for StateStruct { fn deserialize (payload : & [u8]) -> Self { Self { battery_voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , cpu_temperature : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , flags : payload [8usize] . into () , cell_voltages_length : u8 :: from_le_bytes (payload [9usize .. 9usize + 1usize] . try_into () . expect ("Wrong slice length")) , cell_voltages : payload [9usize .. payload . len ()] . chunks_exact (2usize) . into_iter () . map (| a | u16 :: from_le_bytes ((* a) . try_into () . expect ("Wrong slice length"))) . collect :: < Vec < u16 >> () , } } } impl MessageInfo for StateStruct { fn id () -> u16 { 9106u16 } fn name () -> & 'static str { "state" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the frequency to automatically output state messages."] # [doc = "# Arguments"] # [doc = "* `rate` \\[Hz\\] - Rate to stream `state` messages. 0~100000Hz"] pub async fn set_stream_rate (& self , rate : u32) -> Result < () , PingError > { let request = Messages :: SetStreamRate (SetStreamRateStruct { rate , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetStreamRateStruct :: id ()) . await } # [doc = "Get the undervoltage timeout"] pub async fn cell_timeout (& self) -> Result < CellTimeoutStruct , PingError > { self . request () . await } # [doc = "Get the over-current timeout"] pub async fn current_timeout (& self) -> Result < CurrentTimeoutStruct , PingError > { self . request () . await } # [doc = "get the maximum allowed battery current"] pub async fn current_max (& self) -> Result < CurrentMaxStruct , PingError > { self . request () . await } # [doc = "Get the over-temperature timeout"] pub async fn temperature_timeout (& self) -> Result < TemperatureTimeoutStruct , PingError > { self . request () . await } # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] # [doc = "# Arguments"] # [doc = "* `setting` - 0~999: x = 0~0.999"] pub async fn set_lpf_setting (& self , setting : u16) -> Result < () , PingError > { let request = Messages :: SetLpfSetting (SetLpfSettingStruct { setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSettingStruct :: id ()) . await } # [doc = "Set the under-voltage timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_cell_voltage_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageTimeout (SetCellVoltageTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageTimeoutStruct :: id ()) . await } # [doc = "Set the maximum allowed battery current"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centiampere\\] - The maximum allowed battery current 0~20000 = 0~200A"] pub async fn set_current_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentMax (SetCurrentMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentMaxStruct :: id ()) . await } # [doc = "the frequency to take adc samples and run the filter."] # [doc = "# Arguments"] # [doc = "* `sample_frequency` - sample frequency in Hz. 1~100000"] pub async fn set_lpf_sample_frequency (& self , sample_frequency : u32) -> Result < () , PingError > { let request = Messages :: SetLpfSampleFrequency (SetLpfSampleFrequencyStruct { sample_frequency , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSampleFrequencyStruct :: id ()) . await } # [doc = "Set the maximum allowed battery temperature"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centidegrees Centigrade\\] - The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] pub async fn set_temperature_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureMax (SetTemperatureMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureMaxStruct :: id ()) . await } # [doc = "Get the maximum allowed battery temperature"] pub async fn temperature_max (& self) -> Result < TemperatureMaxStruct , PingError > { self . request () . await } # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub async fn events (& self) -> Result < EventsStruct , PingError > { self . request () . await } # [doc = "Set the over-current timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_current_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentTimeout (SetCurrentTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentTimeoutStruct :: id ()) . await } # [doc = "Set the over-temperature timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_temperature_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureTimeout (SetTemperatureTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureTimeoutStruct :: id ()) . await } # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] # [doc = "# Arguments"] pub async fn erase_flash (& self ,) -> Result < () , PingError > { let request = Messages :: EraseFlash (EraseFlashStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Reset parameter configuration to default values."] # [doc = "# Arguments"] pub async fn reset_defaults (& self ,) -> Result < () , PingError > { let request = Messages :: ResetDefaults (ResetDefaultsStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "reboot the system"] # [doc = "# Arguments"] # [doc = "* `goto_bootloader` - 0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] pub async fn reboot (& self , goto_bootloader : u8) -> Result < () , PingError > { let request = Messages :: Reboot (RebootStruct { goto_bootloader , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Get the minimum allowed cell voltage"] pub async fn cell_voltage_min (& self) -> Result < CellVoltageMinStruct , PingError > { self . request () . await } # [doc = "Set the minimum allowed cell voltage"] # [doc = "# Arguments"] # [doc = "* `limit` \\[millivolt\\] - The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] pub async fn set_cell_voltage_minimum (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageMinimum (SetCellVoltageMinimumStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageMinimumStruct :: id ()) . await } # [doc = "Get the current state of the device"] pub async fn state (& self) -> Result < StateStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetStreamRate (..) => "set_stream_rate" , Messages :: CellTimeout (..) => "cell_timeout" , Messages :: CurrentTimeout (..) => "current_timeout" , Messages :: CurrentMax (..) => "current_max" , Messages :: TemperatureTimeout (..) => "temperature_timeout" , Messages :: SetLpfSetting (..) => "set_lpf_setting" , Messages :: SetCellVoltageTimeout (..) => "set_cell_voltage_timeout" , Messages :: SetCurrentMax (..) => "set_current_max" , Messages :: SetLpfSampleFrequency (..) => "set_lpf_sample_frequency" , Messages :: SetTemperatureMax (..) => "set_temperature_max" , Messages :: TemperatureMax (..) => "temperature_max" , Messages :: Events (..) => "events" , Messages :: SetCurrentTimeout (..) => "set_current_timeout" , Messages :: SetTemperatureTimeout (..) => "set_temperature_timeout" , Messages :: EraseFlash (..) => "erase_flash" , Messages :: ResetDefaults (..) => "reset_defaults" , Messages :: Reboot (..) => "reboot" , Messages :: CellVoltageMin (..) => "cell_voltage_min" , Messages :: SetCellVoltageMinimum (..) => "set_cell_voltage_minimum" , Messages :: State (..) => "state" , } } fn message_id (& self) -> u16 { match self { Messages :: SetStreamRate (..) => 9006u16 , Messages :: CellTimeout (..) => 9101u16 , Messages :: CurrentTimeout (..) => 9103u16 , Messages :: CurrentMax (..) => 9102u16 , Messages :: TemperatureTimeout (..) => 9105u16 , Messages :: SetLpfSetting (..) => 9008u16 , Messages :: SetCellVoltageTimeout (..) => 9001u16 , Messages :: SetCurrentMax (..) => 9002u16 , Messages :: SetLpfSampleFrequency (..) => 9007u16 , Messages :: SetTemperatureMax (..) => 9004u16 , Messages :: TemperatureMax (..) => 9104u16 , Messages :: Events (..) => 9107u16 , Messages :: SetCurrentTimeout (..) => 9003u16 , Messages :: SetTemperatureTimeout (..) => 9005u16 , Messages :: EraseFlash (..) => 9201u16 , Messages :: ResetDefaults (..) => 9202u16 , Messages :: Reboot (..) => 9200u16 , Messages :: CellVoltageMin (..) => 9100u16 , Messages :: SetCellVoltageMinimum (..) => 9000u16 , Messages :: State (..) => 9106u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_stream_rate" => Ok (9006u16) , "cell_timeout" => Ok (9101u16) , "current_timeout" => Ok (9103u16) , "current_max" => Ok (9102u16) , "temperature_timeout" => Ok (9105u16) , "set_lpf_setting" => Ok (9008u16) , "set_cell_voltage_timeout" => Ok (9001u16) , "set_current_max" => Ok (9002u16) , "set_lpf_sample_frequency" => Ok (9007u16) , "set_temperature_max" => Ok (9004u16) , "temperature_max" => Ok (9104u16) , "events" => Ok (9107u16) , "set_current_timeout" => Ok (9003u16) , "set_temperature_timeout" => Ok (9005u16) , "erase_flash" => Ok (9201u16) , "reset_defaults" => Ok (9202u16) , "reboot" => Ok (9200u16) , "cell_voltage_min" => Ok (9100u16) , "set_cell_voltage_minimum" => Ok (9000u16) , "state" => Ok (9106u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetStreamRate (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSampleFrequency (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Events (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: EraseFlash (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ResetDefaults (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reboot (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellVoltageMin (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageMinimum (content) => (content as & dyn SerializePayload) . serialize () , Messages :: State (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 9006u16 => Messages :: SetStreamRate (< SetStreamRateStruct as DeserializePayload > :: deserialize (payload)) , 9101u16 => Messages :: CellTimeout (< CellTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9103u16 => Messages :: CurrentTimeout (< CurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9102u16 => Messages :: CurrentMax (< CurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9105u16 => Messages :: TemperatureTimeout (< TemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9008u16 => Messages :: SetLpfSetting (< SetLpfSettingStruct as DeserializePayload > :: deserialize (payload)) , 9001u16 => Messages :: SetCellVoltageTimeout (< SetCellVoltageTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9002u16 => Messages :: SetCurrentMax (< SetCurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9007u16 => Messages :: SetLpfSampleFrequency (< SetLpfSampleFrequencyStruct as DeserializePayload > :: deserialize (payload)) , 9004u16 => Messages :: SetTemperatureMax (< SetTemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9104u16 => Messages :: TemperatureMax (< TemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9107u16 => Messages :: Events (< EventsStruct as DeserializePayload > :: deserialize (payload)) , 9003u16 => Messages :: SetCurrentTimeout (< SetCurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9005u16 => Messages :: SetTemperatureTimeout (< SetTemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9201u16 => Messages :: EraseFlash (< EraseFlashStruct as DeserializePayload > :: deserialize (payload)) , 9202u16 => Messages :: ResetDefaults (< ResetDefaultsStruct as DeserializePayload > :: deserialize (payload)) , 9200u16 => Messages :: Reboot (< RebootStruct as DeserializePayload > :: deserialize (payload)) , 9100u16 => Messages :: CellVoltageMin (< CellVoltageMinStruct as DeserializePayload > :: deserialize (payload)) , 9000u16 => Messages :: SetCellVoltageMinimum (< SetCellVoltageMinimumStruct as DeserializePayload > :: deserialize (payload)) , 9106u16 => Messages :: State (< StateStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetStreamRate (SetStreamRateStruct) , CellTimeout (CellTimeoutStruct) , CurrentTimeout (CurrentTimeoutStruct) , CurrentMax (CurrentMaxStruct) , TemperatureTimeout (TemperatureTimeoutStruct) , SetLpfSetting (SetLpfSettingStruct) , SetCellVoltageTimeout (SetCellVoltageTimeoutStruct) , SetCurrentMax (SetCurrentMaxStruct) , SetLpfSampleFrequency (SetLpfSampleFrequencyStruct) , SetTemperatureMax (SetTemperatureMaxStruct) , TemperatureMax (TemperatureMaxStruct) , Events (EventsStruct) , SetCurrentTimeout (SetCurrentTimeoutStruct) , SetTemperatureTimeout (SetTemperatureTimeoutStruct) , EraseFlash (EraseFlashStruct) , ResetDefaults (ResetDefaultsStruct) , Reboot (RebootStruct) , CellVoltageMin (CellVoltageMinStruct) , SetCellVoltageMinimum (SetCellVoltageMinimumStruct) , State (StateStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetStreamRate (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSampleFrequency (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Events (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: EraseFlash (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ResetDefaults (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reboot (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellVoltageMin (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageMinimum (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: State (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the frequency to automatically output state messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the frequency to automatically output state messages."] pub struct SetStreamRateStruct { # [doc = "Rate to stream `state` messages. 0~100000Hz"] # [cfg_attr (feature = "schemars" , schemars (description = "Rate to stream `state` messages. 0~100000Hz"))] pub rate : u32 , } impl SerializePayload for SetStreamRateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . rate . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetStreamRateStruct { fn deserialize (payload : & [u8]) -> Self { Self { rate : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetStreamRateStruct { fn id () -> u16 { 9006u16 } fn name () -> & 'static str { "set_stream_rate" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the undervoltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the undervoltage timeout"] pub struct CellTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CellTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellTimeoutStruct { fn id () -> u16 { 9101u16 } fn name () -> & 'static str { "cell_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-current timeout"] pub struct CurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentTimeoutStruct { fn id () -> u16 { 9103u16 } fn name () -> & 'static str { "current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "get the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "get the maximum allowed battery current"] pub struct CurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for CurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentMaxStruct { fn id () -> u16 { 9102u16 } fn name () -> & 'static str { "current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-temperature timeout"] pub struct TemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for TemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureTimeoutStruct { fn id () -> u16 { 9105u16 } fn name () -> & 'static str { "temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] pub struct SetLpfSettingStruct { # [doc = "0~999: x = 0~0.999"] # [cfg_attr (feature = "schemars" , schemars (description = "0~999: x = 0~0.999"))] pub setting : u16 , } impl SerializePayload for SetLpfSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { setting : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSettingStruct { fn id () -> u16 { 9008u16 } fn name () -> & 'static str { "set_lpf_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the under-voltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the under-voltage timeout"] pub struct SetCellVoltageTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCellVoltageTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageTimeoutStruct { fn id () -> u16 { 9001u16 } fn name () -> & 'static str { "set_cell_voltage_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery current"] pub struct SetCurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for SetCurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentMaxStruct { fn id () -> u16 { 9002u16 } fn name () -> & 'static str { "set_current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "the frequency to take adc samples and run the filter."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "the frequency to take adc samples and run the filter."] pub struct SetLpfSampleFrequencyStruct { # [doc = "sample frequency in Hz. 1~100000"] # [cfg_attr (feature = "schemars" , schemars (description = "sample frequency in Hz. 1~100000"))] pub sample_frequency : u32 , } impl SerializePayload for SetLpfSampleFrequencyStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . sample_frequency . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSampleFrequencyStruct { fn deserialize (payload : & [u8]) -> Self { Self { sample_frequency : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSampleFrequencyStruct { fn id () -> u16 { 9007u16 } fn name () -> & 'static str { "set_lpf_sample_frequency" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery temperature"] pub struct SetTemperatureMaxStruct { # [doc = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetTemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureMaxStruct { fn id () -> u16 { 9004u16 } fn name () -> & 'static str { "set_temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the maximum allowed battery temperature"] pub struct TemperatureMaxStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for TemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureMaxStruct { fn id () -> u16 { 9104u16 } fn name () -> & 'static str { "temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub struct EventsStruct { # [doc = "The number of under-voltage events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of under-voltage events"))] pub voltage : u16 , # [doc = "The number of over-current events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-current events"))] pub current : u16 , # [doc = "The number of over-temperature events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-temperature events"))] pub temperature : u16 , } impl SerializePayload for EventsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . current . to_le_bytes ()) ; buffer . extend_from_slice (& self . temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for EventsStruct { fn deserialize (payload : & [u8]) -> Self { Self { voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for EventsStruct { fn id () -> u16 { 9107u16 } fn name () -> & 'static str { "events" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-current timeout"] pub struct SetCurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentTimeoutStruct { fn id () -> u16 { 9003u16 } fn name () -> & 'static str { "set_current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-temperature timeout"] pub struct SetTemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetTemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureTimeoutStruct { fn id () -> u16 { 9005u16 } fn name () -> & 'static str { "set_temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] pub struct EraseFlashStruct { } impl SerializePayload for EraseFlashStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for EraseFlashStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for EraseFlashStruct { fn id () -> u16 { 9201u16 } fn name () -> & 'static str { "erase_flash" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset parameter configuration to default values."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset parameter configuration to default values."] pub struct ResetDefaultsStruct { } impl SerializePayload for ResetDefaultsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for ResetDefaultsStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for ResetDefaultsStruct { fn id () -> u16 { 9202u16 } fn name () -> & 'static str { "reset_defaults" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "reboot the system"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "reboot the system"] pub struct RebootStruct { # [doc = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"))] pub goto_bootloader : u8 , } impl SerializePayload for RebootStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . goto_bootloader . to_le_bytes ()) ; buffer } } impl DeserializePayload for RebootStruct { fn deserialize (payload : & [u8]) -> Self { Self { goto_bootloader : <u8 as Into<_>>::into(payload [0usize]) , } } } impl MessageInfo for RebootStruct { fn id () -> u16 { 9200u16 } fn name () -> & 'static str { "reboot" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the minimum allowed cell voltage"] pub struct CellVoltageMinStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for CellVoltageMinStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellVoltageMinStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellVoltageMinStruct { fn id () -> u16 { 9100u16 } fn name () -> & 'static str { "cell_voltage_min" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the minimum allowed cell voltage"] pub struct SetCellVoltageMinimumStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetCellVoltageMinimumStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageMinimumStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageMinimumStruct { fn id () -> u16 { 9000u16 } fn name () -> & 'static str { "set_cell_voltage_minimum" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the current state of the device"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the current state of the device"] pub struct StateStruct { # [doc = "The main battery voltage"] # [cfg_attr (feature = "schemars" , schemars (description = "The main battery voltage"))] pub battery_voltage : u16 , # [doc = "The current measurement"] # [cfg_attr (feature = "schemars" , schemars (description = "The current measurement"))] pub battery_current : u16 , # [doc = "The battery temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The battery temperature"))] pub battery_temperature : u16 , # [doc = "The cpu temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The cpu temperature"))] pub cpu_temperature : u16 , # [doc = "flags indicating if any of the configured limits are currently exceeded"] # [cfg_attr (feature = "schemars" , schemars (description = "flags indicating if any of the configured limits are currently exceeded"))] pub flags : u8 , # [doc = "Array containing cell voltages"] # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages_length : u8 , # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages : Vec < u16 > , } impl SerializePayload for StateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . battery_voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_current . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . cpu_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . flags . to_le_bytes ()) ; buffer . extend_from_slice (& self . cell_voltages_length . to_le_bytes ()) ; for value in self . cell_voltages . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for StateStruct { fn deserialize (payload : & [u8]) -> Self { Self { battery_voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , cpu_temperature : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , flags : payload [8usize] . into () , cell_voltages_length : u8 :: from_le_bytes (payload [9usize .. 9usize + 1usize] . try_into () . expect ("Wrong slice length")) , cell_voltages : payload [9usize .. payload . len ()] . chunks_exact (2usize) . into_iter () . map (| a | u16 :: from_le_bytes ((* a) . try_into () . expect ("Wrong slice length"))) . collect :: < Vec < u16 >> () , } } } impl MessageInfo for StateStruct { fn id () -> u16 { 9106u16 } fn name () -> & 'static str { "state" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the frequency to automatically output state messages."] # [doc = "# Arguments"] # [doc = "* `rate` \\[Hz\\] - Rate to stream `state` messages. 0~100000Hz"] pub async fn set_stream_rate (& self , rate : u32) -> Result < () , PingError > { let request = Messages :: SetStreamRate (SetStreamRateStruct { rate , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetStreamRateStruct :: id ()) . await } # [doc = "Get the undervoltage timeout"] pub async fn cell_timeout (& self) -> Result < CellTimeoutStruct , PingError > { self . request () . await } # [doc = "Get the over-current timeout"] pub async fn current_timeout (& self) -> Result < CurrentTimeoutStruct , PingError > { self . request () . await } # [doc = "get the maximum allowed battery current"] pub async fn current_max (& self) -> Result < CurrentMaxStruct , PingError > { self . request () . await } # [doc = "Get the over-temperature timeout"] pub async fn temperature_timeout (& self) -> Result < TemperatureTimeoutStruct , PingError > { self . request () . await } # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] # [doc = "# Arguments"] # [doc = "* `setting` - 0~999: x = 0~0.999"] pub async fn set_lpf_setting (& self , setting : u16) -> Result < () , PingError > { let request = Messages :: SetLpfSetting (SetLpfSettingStruct { setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSettingStruct :: id ()) . await } # [doc = "Set the under-voltage timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_cell_voltage_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageTimeout (SetCellVoltageTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageTimeoutStruct :: id ()) . await } # [doc = "Set the maximum allowed battery current"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centiampere\\] - The maximum allowed battery current 0~20000 = 0~200A"] pub async fn set_current_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentMax (SetCurrentMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentMaxStruct :: id ()) . await } # [doc = "the frequency to take adc samples and run the filter."] # [doc = "# Arguments"] # [doc = "* `sample_frequency` - sample frequency in Hz. 1~100000"] pub async fn set_lpf_sample_frequency (& self , sample_frequency : u32) -> Result < () , PingError > { let request = Messages :: SetLpfSampleFrequency (SetLpfSampleFrequencyStruct { sample_frequency , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSampleFrequencyStruct :: id ()) . await } # [doc = "Set the maximum allowed battery temperature"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centidegrees Centigrade\\] - The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] pub async fn set_temperature_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureMax (SetTemperatureMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureMaxStruct :: id ()) . await } # [doc = "Get the maximum allowed battery temperature"] pub async fn temperature_max (& self) -> Result < TemperatureMaxStruct , PingError > { self . request () . await } # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub async fn events (& self) -> Result < EventsStruct , PingError > { self . request () . await } # [doc = "Set the over-current timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_current_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentTimeout (SetCurrentTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentTimeoutStruct :: id ()) . await } # [doc = "Set the over-temperature timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_temperature_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureTimeout (SetTemperatureTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureTimeoutStruct :: id ()) . await } # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] # [doc = "# Arguments"] pub async fn erase_flash (& self ,) -> Result < () , PingError > { let request = Messages :: EraseFlash (EraseFlashStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Reset parameter configuration to default values."] # [doc = "# Arguments"] pub async fn reset_defaults (& self ,) -> Result < () , PingError > { let request = Messages :: ResetDefaults (ResetDefaultsStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "reboot the system"] # [doc = "# Arguments"] # [doc = "* `goto_bootloader` - 0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] pub async fn reboot (& self , goto_bootloader : u8) -> Result < () , PingError > { let request = Messages :: Reboot (RebootStruct { goto_bootloader , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Get the minimum allowed cell voltage"] pub async fn cell_voltage_min (& self) -> Result < CellVoltageMinStruct , PingError > { self . request () . await } # [doc = "Set the minimum allowed cell voltage"] # [doc = "# Arguments"] # [doc = "* `limit` \\[millivolt\\] - The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] pub async fn set_cell_voltage_minimum (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageMinimum (SetCellVoltageMinimumStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageMinimumStruct :: id ()) . await } # [doc = "Get the current state of the device"] pub async fn state (& self) -> Result < StateStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetStreamRate (..) => "set_stream_rate" , Messages :: CellTimeout (..) => "cell_timeout" , Messages :: CurrentTimeout (..) => "current_timeout" , Messages :: CurrentMax (..) => "current_max" , Messages :: TemperatureTimeout (..) => "temperature_timeout" , Messages :: SetLpfSetting (..) => "set_lpf_setting" , Messages :: SetCellVoltageTimeout (..) => "set_cell_voltage_timeout" , Messages :: SetCurrentMax (..) => "set_current_max" , Messages :: SetLpfSampleFrequency (..) => "set_lpf_sample_frequency" , Messages :: SetTemperatureMax (..) => "set_temperature_max" , Messages :: TemperatureMax (..) => "temperature_max" , Messages :: Events (..) => "events" , Messages :: SetCurrentTimeout (..) => "set_current_timeout" , Messages :: SetTemperatureTimeout (..) => "set_temperature_timeout" , Messages :: EraseFlash (..) => "erase_flash" , Messages :: ResetDefaults (..) => "reset_defaults" , Messages :: Reboot (..) => "reboot" , Messages :: CellVoltageMin (..) => "cell_voltage_min" , Messages :: SetCellVoltageMinimum (..) => "set_cell_voltage_minimum" , Messages :: State (..) => "state" , } } fn message_id (& self) -> u16 { match self { Messages :: SetStreamRate (..) => 9006u16 , Messages :: CellTimeout (..) => 9101u16 , Messages :: CurrentTimeout (..) => 9103u16 , Messages :: CurrentMax (..) => 9102u16 , Messages :: TemperatureTimeout (..) => 9105u16 , Messages :: SetLpfSetting (..) => 9008u16 , Messages :: SetCellVoltageTimeout (..) => 9001u16 , Messages :: SetCurrentMax (..) => 9002u16 , Messages :: SetLpfSampleFrequency (..) => 9007u16 , Messages :: SetTemperatureMax (..) => 9004u16 , Messages :: TemperatureMax (..) => 9104u16 , Messages :: Events (..) => 9107u16 , Messages :: SetCurrentTimeout (..) => 9003u16 , Messages :: SetTemperatureTimeout (..) => 9005u16 , Messages :: EraseFlash (..) => 9201u16 , Messages :: ResetDefaults (..) => 9202u16 , Messages :: Reboot (..) => 9200u16 , Messages :: CellVoltageMin (..) => 9100u16 , Messages :: SetCellVoltageMinimum (..) => 9000u16 , Messages :: State (..) => 9106u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_stream_rate" => Ok (9006u16) , "cell_timeout" => Ok (9101u16) , "current_timeout" => Ok (9103u16) , "current_max" => Ok (9102u16) , "temperature_timeout" => Ok (9105u16) , "set_lpf_setting" => Ok (9008u16) , "set_cell_voltage_timeout" => Ok (9001u16) , "set_current_max" => Ok (9002u16) , "set_lpf_sample_frequency" => Ok (9007u16) , "set_temperature_max" => Ok (9004u16) , "temperature_max" => Ok (9104u16) , "events" => Ok (9107u16) , "set_current_timeout" => Ok (9003u16) , "set_temperature_timeout" => Ok (9005u16) , "erase_flash" => Ok (9201u16) , "reset_defaults" => Ok (9202u16) , "reboot" => Ok (9200u16) , "cell_voltage_min" => Ok (9100u16) , "set_cell_voltage_minimum" => Ok (9000u16) , "state" => Ok (9106u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetStreamRate (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSampleFrequency (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Events (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: EraseFlash (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ResetDefaults (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reboot (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellVoltageMin (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageMinimum (content) => (content as & dyn SerializePayload) . serialize () , Messages :: State (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 9006u16 => Messages :: SetStreamRate (< SetStreamRateStruct as DeserializePayload > :: deserialize (payload)) , 9101u16 => Messages :: CellTimeout (< CellTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9103u16 => Messages :: CurrentTimeout (< CurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9102u16 => Messages :: CurrentMax (< CurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9105u16 => Messages :: TemperatureTimeout (< TemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9008u16 => Messages :: SetLpfSetting (< SetLpfSettingStruct as DeserializePayload > :: deserialize (payload)) , 9001u16 => Messages :: SetCellVoltageTimeout (< SetCellVoltageTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9002u16 => Messages :: SetCurrentMax (< SetCurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9007u16 => Messages :: SetLpfSampleFrequency (< SetLpfSampleFrequencyStruct as DeserializePayload > :: deserialize (payload)) , 9004u16 => Messages :: SetTemperatureMax (< SetTemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9104u16 => Messages :: TemperatureMax (< TemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9107u16 => Messages :: Events (< EventsStruct as DeserializePayload > :: deserialize (payload)) , 9003u16 => Messages :: SetCurrentTimeout (< SetCurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9005u16 => Messages :: SetTemperatureTimeout (< SetTemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9201u16 => Messages :: EraseFlash (< EraseFlashStruct as DeserializePayload > :: deserialize (payload)) , 9202u16 => Messages :: ResetDefaults (< ResetDefaultsStruct as DeserializePayload > :: deserialize (payload)) , 9200u16 => Messages :: Reboot (< RebootStruct as DeserializePayload > :: deserialize (payload)) , 9100u16 => Messages :: CellVoltageMin (< CellVoltageMinStruct as DeserializePayload > :: deserialize (payload)) , 9000u16 => Messages :: SetCellVoltageMinimum (< SetCellVoltageMinimumStruct as DeserializePayload > :: deserialize (payload)) , 9106u16 => Messages :: State (< StateStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/bluebps.rs:1:31915
[INFO] [stdout]   |
[INFO] [stdout] 1 | ..._into () . expect ("Wrong slice length")) , flags : payload [8usize] . into () , cell_voltages_length : u8 :: from_le_bytes (paylo...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetStreamRate (SetStreamRateStruct) , CellTimeout (CellTimeoutStruct) , CurrentTimeout (CurrentTimeoutStruct) , CurrentMax (CurrentMaxStruct) , TemperatureTimeout (TemperatureTimeoutStruct) , SetLpfSetting (SetLpfSettingStruct) , SetCellVoltageTimeout (SetCellVoltageTimeoutStruct) , SetCurrentMax (SetCurrentMaxStruct) , SetLpfSampleFrequency (SetLpfSampleFrequencyStruct) , SetTemperatureMax (SetTemperatureMaxStruct) , TemperatureMax (TemperatureMaxStruct) , Events (EventsStruct) , SetCurrentTimeout (SetCurrentTimeoutStruct) , SetTemperatureTimeout (SetTemperatureTimeoutStruct) , EraseFlash (EraseFlashStruct) , ResetDefaults (ResetDefaultsStruct) , Reboot (RebootStruct) , CellVoltageMin (CellVoltageMinStruct) , SetCellVoltageMinimum (SetCellVoltageMinimumStruct) , State (StateStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetStreamRate (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSampleFrequency (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Events (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: EraseFlash (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ResetDefaults (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reboot (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellVoltageMin (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageMinimum (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: State (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the frequency to automatically output state messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the frequency to automatically output state messages."] pub struct SetStreamRateStruct { # [doc = "Rate to stream `state` messages. 0~100000Hz"] # [cfg_attr (feature = "schemars" , schemars (description = "Rate to stream `state` messages. 0~100000Hz"))] pub rate : u32 , } impl SerializePayload for SetStreamRateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . rate . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetStreamRateStruct { fn deserialize (payload : & [u8]) -> Self { Self { rate : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetStreamRateStruct { fn id () -> u16 { 9006u16 } fn name () -> & 'static str { "set_stream_rate" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the undervoltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the undervoltage timeout"] pub struct CellTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CellTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellTimeoutStruct { fn id () -> u16 { 9101u16 } fn name () -> & 'static str { "cell_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-current timeout"] pub struct CurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentTimeoutStruct { fn id () -> u16 { 9103u16 } fn name () -> & 'static str { "current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "get the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "get the maximum allowed battery current"] pub struct CurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for CurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentMaxStruct { fn id () -> u16 { 9102u16 } fn name () -> & 'static str { "current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-temperature timeout"] pub struct TemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for TemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureTimeoutStruct { fn id () -> u16 { 9105u16 } fn name () -> & 'static str { "temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] pub struct SetLpfSettingStruct { # [doc = "0~999: x = 0~0.999"] # [cfg_attr (feature = "schemars" , schemars (description = "0~999: x = 0~0.999"))] pub setting : u16 , } impl SerializePayload for SetLpfSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { setting : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSettingStruct { fn id () -> u16 { 9008u16 } fn name () -> & 'static str { "set_lpf_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the under-voltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the under-voltage timeout"] pub struct SetCellVoltageTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCellVoltageTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageTimeoutStruct { fn id () -> u16 { 9001u16 } fn name () -> & 'static str { "set_cell_voltage_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery current"] pub struct SetCurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for SetCurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentMaxStruct { fn id () -> u16 { 9002u16 } fn name () -> & 'static str { "set_current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "the frequency to take adc samples and run the filter."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "the frequency to take adc samples and run the filter."] pub struct SetLpfSampleFrequencyStruct { # [doc = "sample frequency in Hz. 1~100000"] # [cfg_attr (feature = "schemars" , schemars (description = "sample frequency in Hz. 1~100000"))] pub sample_frequency : u32 , } impl SerializePayload for SetLpfSampleFrequencyStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . sample_frequency . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSampleFrequencyStruct { fn deserialize (payload : & [u8]) -> Self { Self { sample_frequency : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSampleFrequencyStruct { fn id () -> u16 { 9007u16 } fn name () -> & 'static str { "set_lpf_sample_frequency" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery temperature"] pub struct SetTemperatureMaxStruct { # [doc = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetTemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureMaxStruct { fn id () -> u16 { 9004u16 } fn name () -> & 'static str { "set_temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the maximum allowed battery temperature"] pub struct TemperatureMaxStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for TemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureMaxStruct { fn id () -> u16 { 9104u16 } fn name () -> & 'static str { "temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub struct EventsStruct { # [doc = "The number of under-voltage events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of under-voltage events"))] pub voltage : u16 , # [doc = "The number of over-current events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-current events"))] pub current : u16 , # [doc = "The number of over-temperature events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-temperature events"))] pub temperature : u16 , } impl SerializePayload for EventsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . current . to_le_bytes ()) ; buffer . extend_from_slice (& self . temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for EventsStruct { fn deserialize (payload : & [u8]) -> Self { Self { voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for EventsStruct { fn id () -> u16 { 9107u16 } fn name () -> & 'static str { "events" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-current timeout"] pub struct SetCurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentTimeoutStruct { fn id () -> u16 { 9003u16 } fn name () -> & 'static str { "set_current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-temperature timeout"] pub struct SetTemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetTemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureTimeoutStruct { fn id () -> u16 { 9005u16 } fn name () -> & 'static str { "set_temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] pub struct EraseFlashStruct { } impl SerializePayload for EraseFlashStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for EraseFlashStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for EraseFlashStruct { fn id () -> u16 { 9201u16 } fn name () -> & 'static str { "erase_flash" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset parameter configuration to default values."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset parameter configuration to default values."] pub struct ResetDefaultsStruct { } impl SerializePayload for ResetDefaultsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for ResetDefaultsStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for ResetDefaultsStruct { fn id () -> u16 { 9202u16 } fn name () -> & 'static str { "reset_defaults" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "reboot the system"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "reboot the system"] pub struct RebootStruct { # [doc = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"))] pub goto_bootloader : u8 , } impl SerializePayload for RebootStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . goto_bootloader . to_le_bytes ()) ; buffer } } impl DeserializePayload for RebootStruct { fn deserialize (payload : & [u8]) -> Self { Self { goto_bootloader : payload [0usize] . into () , } } } impl MessageInfo for RebootStruct { fn id () -> u16 { 9200u16 } fn name () -> & 'static str { "reboot" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the minimum allowed cell voltage"] pub struct CellVoltageMinStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for CellVoltageMinStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellVoltageMinStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellVoltageMinStruct { fn id () -> u16 { 9100u16 } fn name () -> & 'static str { "cell_voltage_min" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the minimum allowed cell voltage"] pub struct SetCellVoltageMinimumStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetCellVoltageMinimumStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageMinimumStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageMinimumStruct { fn id () -> u16 { 9000u16 } fn name () -> & 'static str { "set_cell_voltage_minimum" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the current state of the device"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the current state of the device"] pub struct StateStruct { # [doc = "The main battery voltage"] # [cfg_attr (feature = "schemars" , schemars (description = "The main battery voltage"))] pub battery_voltage : u16 , # [doc = "The current measurement"] # [cfg_attr (feature = "schemars" , schemars (description = "The current measurement"))] pub battery_current : u16 , # [doc = "The battery temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The battery temperature"))] pub battery_temperature : u16 , # [doc = "The cpu temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The cpu temperature"))] pub cpu_temperature : u16 , # [doc = "flags indicating if any of the configured limits are currently exceeded"] # [cfg_attr (feature = "schemars" , schemars (description = "flags indicating if any of the configured limits are currently exceeded"))] pub flags : u8 , # [doc = "Array containing cell voltages"] # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages_length : u8 , # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages : Vec < u16 > , } impl SerializePayload for StateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . battery_voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_current . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . cpu_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . flags . to_le_bytes ()) ; buffer . extend_from_slice (& self . cell_voltages_length . to_le_bytes ()) ; for value in self . cell_voltages . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for StateStruct { fn deserialize (payload : & [u8]) -> Self { Self { battery_voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , cpu_temperature : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , flags : payload [8usize] . into () , cell_voltages_length : u8 :: from_le_bytes (payload [9usize .. 9usize + 1usize] . try_into () . expect ("Wrong slice length")) , cell_voltages : payload [9usize .. payload . len ()] . chunks_exact (2usize) . into_iter () . map (| a | u16 :: from_le_bytes ((* a) . try_into () . expect ("Wrong slice length"))) . collect :: < Vec < u16 >> () , } } } impl MessageInfo for StateStruct { fn id () -> u16 { 9106u16 } fn name () -> & 'static str { "state" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the frequency to automatically output state messages."] # [doc = "# Arguments"] # [doc = "* `rate` \\[Hz\\] - Rate to stream `state` messages. 0~100000Hz"] pub async fn set_stream_rate (& self , rate : u32) -> Result < () , PingError > { let request = Messages :: SetStreamRate (SetStreamRateStruct { rate , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetStreamRateStruct :: id ()) . await } # [doc = "Get the undervoltage timeout"] pub async fn cell_timeout (& self) -> Result < CellTimeoutStruct , PingError > { self . request () . await } # [doc = "Get the over-current timeout"] pub async fn current_timeout (& self) -> Result < CurrentTimeoutStruct , PingError > { self . request () . await } # [doc = "get the maximum allowed battery current"] pub async fn current_max (& self) -> Result < CurrentMaxStruct , PingError > { self . request () . await } # [doc = "Get the over-temperature timeout"] pub async fn temperature_timeout (& self) -> Result < TemperatureTimeoutStruct , PingError > { self . request () . await } # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] # [doc = "# Arguments"] # [doc = "* `setting` - 0~999: x = 0~0.999"] pub async fn set_lpf_setting (& self , setting : u16) -> Result < () , PingError > { let request = Messages :: SetLpfSetting (SetLpfSettingStruct { setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSettingStruct :: id ()) . await } # [doc = "Set the under-voltage timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_cell_voltage_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageTimeout (SetCellVoltageTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageTimeoutStruct :: id ()) . await } # [doc = "Set the maximum allowed battery current"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centiampere\\] - The maximum allowed battery current 0~20000 = 0~200A"] pub async fn set_current_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentMax (SetCurrentMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentMaxStruct :: id ()) . await } # [doc = "the frequency to take adc samples and run the filter."] # [doc = "# Arguments"] # [doc = "* `sample_frequency` - sample frequency in Hz. 1~100000"] pub async fn set_lpf_sample_frequency (& self , sample_frequency : u32) -> Result < () , PingError > { let request = Messages :: SetLpfSampleFrequency (SetLpfSampleFrequencyStruct { sample_frequency , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSampleFrequencyStruct :: id ()) . await } # [doc = "Set the maximum allowed battery temperature"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centidegrees Centigrade\\] - The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] pub async fn set_temperature_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureMax (SetTemperatureMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureMaxStruct :: id ()) . await } # [doc = "Get the maximum allowed battery temperature"] pub async fn temperature_max (& self) -> Result < TemperatureMaxStruct , PingError > { self . request () . await } # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub async fn events (& self) -> Result < EventsStruct , PingError > { self . request () . await } # [doc = "Set the over-current timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_current_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentTimeout (SetCurrentTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentTimeoutStruct :: id ()) . await } # [doc = "Set the over-temperature timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_temperature_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureTimeout (SetTemperatureTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureTimeoutStruct :: id ()) . await } # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] # [doc = "# Arguments"] pub async fn erase_flash (& self ,) -> Result < () , PingError > { let request = Messages :: EraseFlash (EraseFlashStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Reset parameter configuration to default values."] # [doc = "# Arguments"] pub async fn reset_defaults (& self ,) -> Result < () , PingError > { let request = Messages :: ResetDefaults (ResetDefaultsStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "reboot the system"] # [doc = "# Arguments"] # [doc = "* `goto_bootloader` - 0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] pub async fn reboot (& self , goto_bootloader : u8) -> Result < () , PingError > { let request = Messages :: Reboot (RebootStruct { goto_bootloader , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Get the minimum allowed cell voltage"] pub async fn cell_voltage_min (& self) -> Result < CellVoltageMinStruct , PingError > { self . request () . await } # [doc = "Set the minimum allowed cell voltage"] # [doc = "# Arguments"] # [doc = "* `limit` \\[millivolt\\] - The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] pub async fn set_cell_voltage_minimum (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageMinimum (SetCellVoltageMinimumStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageMinimumStruct :: id ()) . await } # [doc = "Get the current state of the device"] pub async fn state (& self) -> Result < StateStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetStreamRate (..) => "set_stream_rate" , Messages :: CellTimeout (..) => "cell_timeout" , Messages :: CurrentTimeout (..) => "current_timeout" , Messages :: CurrentMax (..) => "current_max" , Messages :: TemperatureTimeout (..) => "temperature_timeout" , Messages :: SetLpfSetting (..) => "set_lpf_setting" , Messages :: SetCellVoltageTimeout (..) => "set_cell_voltage_timeout" , Messages :: SetCurrentMax (..) => "set_current_max" , Messages :: SetLpfSampleFrequency (..) => "set_lpf_sample_frequency" , Messages :: SetTemperatureMax (..) => "set_temperature_max" , Messages :: TemperatureMax (..) => "temperature_max" , Messages :: Events (..) => "events" , Messages :: SetCurrentTimeout (..) => "set_current_timeout" , Messages :: SetTemperatureTimeout (..) => "set_temperature_timeout" , Messages :: EraseFlash (..) => "erase_flash" , Messages :: ResetDefaults (..) => "reset_defaults" , Messages :: Reboot (..) => "reboot" , Messages :: CellVoltageMin (..) => "cell_voltage_min" , Messages :: SetCellVoltageMinimum (..) => "set_cell_voltage_minimum" , Messages :: State (..) => "state" , } } fn message_id (& self) -> u16 { match self { Messages :: SetStreamRate (..) => 9006u16 , Messages :: CellTimeout (..) => 9101u16 , Messages :: CurrentTimeout (..) => 9103u16 , Messages :: CurrentMax (..) => 9102u16 , Messages :: TemperatureTimeout (..) => 9105u16 , Messages :: SetLpfSetting (..) => 9008u16 , Messages :: SetCellVoltageTimeout (..) => 9001u16 , Messages :: SetCurrentMax (..) => 9002u16 , Messages :: SetLpfSampleFrequency (..) => 9007u16 , Messages :: SetTemperatureMax (..) => 9004u16 , Messages :: TemperatureMax (..) => 9104u16 , Messages :: Events (..) => 9107u16 , Messages :: SetCurrentTimeout (..) => 9003u16 , Messages :: SetTemperatureTimeout (..) => 9005u16 , Messages :: EraseFlash (..) => 9201u16 , Messages :: ResetDefaults (..) => 9202u16 , Messages :: Reboot (..) => 9200u16 , Messages :: CellVoltageMin (..) => 9100u16 , Messages :: SetCellVoltageMinimum (..) => 9000u16 , Messages :: State (..) => 9106u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_stream_rate" => Ok (9006u16) , "cell_timeout" => Ok (9101u16) , "current_timeout" => Ok (9103u16) , "current_max" => Ok (9102u16) , "temperature_timeout" => Ok (9105u16) , "set_lpf_setting" => Ok (9008u16) , "set_cell_voltage_timeout" => Ok (9001u16) , "set_current_max" => Ok (9002u16) , "set_lpf_sample_frequency" => Ok (9007u16) , "set_temperature_max" => Ok (9004u16) , "temperature_max" => Ok (9104u16) , "events" => Ok (9107u16) , "set_current_timeout" => Ok (9003u16) , "set_temperature_timeout" => Ok (9005u16) , "erase_flash" => Ok (9201u16) , "reset_defaults" => Ok (9202u16) , "reboot" => Ok (9200u16) , "cell_voltage_min" => Ok (9100u16) , "set_cell_voltage_minimum" => Ok (9000u16) , "state" => Ok (9106u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetStreamRate (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSampleFrequency (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Events (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: EraseFlash (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ResetDefaults (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reboot (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellVoltageMin (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageMinimum (content) => (content as & dyn SerializePayload) . serialize () , Messages :: State (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 9006u16 => Messages :: SetStreamRate (< SetStreamRateStruct as DeserializePayload > :: deserialize (payload)) , 9101u16 => Messages :: CellTimeout (< CellTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9103u16 => Messages :: CurrentTimeout (< CurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9102u16 => Messages :: CurrentMax (< CurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9105u16 => Messages :: TemperatureTimeout (< TemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9008u16 => Messages :: SetLpfSetting (< SetLpfSettingStruct as DeserializePayload > :: deserialize (payload)) , 9001u16 => Messages :: SetCellVoltageTimeout (< SetCellVoltageTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9002u16 => Messages :: SetCurrentMax (< SetCurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9007u16 => Messages :: SetLpfSampleFrequency (< SetLpfSampleFrequencyStruct as DeserializePayload > :: deserialize (payload)) , 9004u16 => Messages :: SetTemperatureMax (< SetTemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9104u16 => Messages :: TemperatureMax (< TemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9107u16 => Messages :: Events (< EventsStruct as DeserializePayload > :: deserialize (payload)) , 9003u16 => Messages :: SetCurrentTimeout (< SetCurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9005u16 => Messages :: SetTemperatureTimeout (< SetTemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9201u16 => Messages :: EraseFlash (< EraseFlashStruct as DeserializePayload > :: deserialize (payload)) , 9202u16 => Messages :: ResetDefaults (< ResetDefaultsStruct as DeserializePayload > :: deserialize (payload)) , 9200u16 => Messages :: Reboot (< RebootStruct as DeserializePayload > :: deserialize (payload)) , 9100u16 => Messages :: CellVoltageMin (< CellVoltageMinStruct as DeserializePayload > :: deserialize (payload)) , 9000u16 => Messages :: SetCellVoltageMinimum (< SetCellVoltageMinimumStruct as DeserializePayload > :: deserialize (payload)) , 9106u16 => Messages :: State (< StateStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetStreamRate (SetStreamRateStruct) , CellTimeout (CellTimeoutStruct) , CurrentTimeout (CurrentTimeoutStruct) , CurrentMax (CurrentMaxStruct) , TemperatureTimeout (TemperatureTimeoutStruct) , SetLpfSetting (SetLpfSettingStruct) , SetCellVoltageTimeout (SetCellVoltageTimeoutStruct) , SetCurrentMax (SetCurrentMaxStruct) , SetLpfSampleFrequency (SetLpfSampleFrequencyStruct) , SetTemperatureMax (SetTemperatureMaxStruct) , TemperatureMax (TemperatureMaxStruct) , Events (EventsStruct) , SetCurrentTimeout (SetCurrentTimeoutStruct) , SetTemperatureTimeout (SetTemperatureTimeoutStruct) , EraseFlash (EraseFlashStruct) , ResetDefaults (ResetDefaultsStruct) , Reboot (RebootStruct) , CellVoltageMin (CellVoltageMinStruct) , SetCellVoltageMinimum (SetCellVoltageMinimumStruct) , State (StateStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetStreamRate (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSampleFrequency (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Events (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: EraseFlash (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ResetDefaults (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reboot (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellVoltageMin (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageMinimum (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: State (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the frequency to automatically output state messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the frequency to automatically output state messages."] pub struct SetStreamRateStruct { # [doc = "Rate to stream `state` messages. 0~100000Hz"] # [cfg_attr (feature = "schemars" , schemars (description = "Rate to stream `state` messages. 0~100000Hz"))] pub rate : u32 , } impl SerializePayload for SetStreamRateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . rate . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetStreamRateStruct { fn deserialize (payload : & [u8]) -> Self { Self { rate : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetStreamRateStruct { fn id () -> u16 { 9006u16 } fn name () -> & 'static str { "set_stream_rate" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the undervoltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the undervoltage timeout"] pub struct CellTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CellTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellTimeoutStruct { fn id () -> u16 { 9101u16 } fn name () -> & 'static str { "cell_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-current timeout"] pub struct CurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentTimeoutStruct { fn id () -> u16 { 9103u16 } fn name () -> & 'static str { "current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "get the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "get the maximum allowed battery current"] pub struct CurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for CurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentMaxStruct { fn id () -> u16 { 9102u16 } fn name () -> & 'static str { "current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-temperature timeout"] pub struct TemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for TemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureTimeoutStruct { fn id () -> u16 { 9105u16 } fn name () -> & 'static str { "temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] pub struct SetLpfSettingStruct { # [doc = "0~999: x = 0~0.999"] # [cfg_attr (feature = "schemars" , schemars (description = "0~999: x = 0~0.999"))] pub setting : u16 , } impl SerializePayload for SetLpfSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { setting : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSettingStruct { fn id () -> u16 { 9008u16 } fn name () -> & 'static str { "set_lpf_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the under-voltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the under-voltage timeout"] pub struct SetCellVoltageTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCellVoltageTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageTimeoutStruct { fn id () -> u16 { 9001u16 } fn name () -> & 'static str { "set_cell_voltage_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery current"] pub struct SetCurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for SetCurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentMaxStruct { fn id () -> u16 { 9002u16 } fn name () -> & 'static str { "set_current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "the frequency to take adc samples and run the filter."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "the frequency to take adc samples and run the filter."] pub struct SetLpfSampleFrequencyStruct { # [doc = "sample frequency in Hz. 1~100000"] # [cfg_attr (feature = "schemars" , schemars (description = "sample frequency in Hz. 1~100000"))] pub sample_frequency : u32 , } impl SerializePayload for SetLpfSampleFrequencyStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . sample_frequency . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSampleFrequencyStruct { fn deserialize (payload : & [u8]) -> Self { Self { sample_frequency : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSampleFrequencyStruct { fn id () -> u16 { 9007u16 } fn name () -> & 'static str { "set_lpf_sample_frequency" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery temperature"] pub struct SetTemperatureMaxStruct { # [doc = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetTemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureMaxStruct { fn id () -> u16 { 9004u16 } fn name () -> & 'static str { "set_temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the maximum allowed battery temperature"] pub struct TemperatureMaxStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for TemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureMaxStruct { fn id () -> u16 { 9104u16 } fn name () -> & 'static str { "temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub struct EventsStruct { # [doc = "The number of under-voltage events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of under-voltage events"))] pub voltage : u16 , # [doc = "The number of over-current events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-current events"))] pub current : u16 , # [doc = "The number of over-temperature events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-temperature events"))] pub temperature : u16 , } impl SerializePayload for EventsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . current . to_le_bytes ()) ; buffer . extend_from_slice (& self . temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for EventsStruct { fn deserialize (payload : & [u8]) -> Self { Self { voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for EventsStruct { fn id () -> u16 { 9107u16 } fn name () -> & 'static str { "events" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-current timeout"] pub struct SetCurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentTimeoutStruct { fn id () -> u16 { 9003u16 } fn name () -> & 'static str { "set_current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-temperature timeout"] pub struct SetTemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetTemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureTimeoutStruct { fn id () -> u16 { 9005u16 } fn name () -> & 'static str { "set_temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] pub struct EraseFlashStruct { } impl SerializePayload for EraseFlashStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for EraseFlashStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for EraseFlashStruct { fn id () -> u16 { 9201u16 } fn name () -> & 'static str { "erase_flash" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset parameter configuration to default values."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset parameter configuration to default values."] pub struct ResetDefaultsStruct { } impl SerializePayload for ResetDefaultsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for ResetDefaultsStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for ResetDefaultsStruct { fn id () -> u16 { 9202u16 } fn name () -> & 'static str { "reset_defaults" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "reboot the system"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "reboot the system"] pub struct RebootStruct { # [doc = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"))] pub goto_bootloader : u8 , } impl SerializePayload for RebootStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . goto_bootloader . to_le_bytes ()) ; buffer } } impl DeserializePayload for RebootStruct { fn deserialize (payload : & [u8]) -> Self { Self { goto_bootloader : payload [0usize] . into () , } } } impl MessageInfo for RebootStruct { fn id () -> u16 { 9200u16 } fn name () -> & 'static str { "reboot" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the minimum allowed cell voltage"] pub struct CellVoltageMinStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for CellVoltageMinStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellVoltageMinStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellVoltageMinStruct { fn id () -> u16 { 9100u16 } fn name () -> & 'static str { "cell_voltage_min" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the minimum allowed cell voltage"] pub struct SetCellVoltageMinimumStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetCellVoltageMinimumStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageMinimumStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageMinimumStruct { fn id () -> u16 { 9000u16 } fn name () -> & 'static str { "set_cell_voltage_minimum" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the current state of the device"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the current state of the device"] pub struct StateStruct { # [doc = "The main battery voltage"] # [cfg_attr (feature = "schemars" , schemars (description = "The main battery voltage"))] pub battery_voltage : u16 , # [doc = "The current measurement"] # [cfg_attr (feature = "schemars" , schemars (description = "The current measurement"))] pub battery_current : u16 , # [doc = "The battery temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The battery temperature"))] pub battery_temperature : u16 , # [doc = "The cpu temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The cpu temperature"))] pub cpu_temperature : u16 , # [doc = "flags indicating if any of the configured limits are currently exceeded"] # [cfg_attr (feature = "schemars" , schemars (description = "flags indicating if any of the configured limits are currently exceeded"))] pub flags : u8 , # [doc = "Array containing cell voltages"] # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages_length : u8 , # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages : Vec < u16 > , } impl SerializePayload for StateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . battery_voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_current . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . cpu_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . flags . to_le_bytes ()) ; buffer . extend_from_slice (& self . cell_voltages_length . to_le_bytes ()) ; for value in self . cell_voltages . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for StateStruct { fn deserialize (payload : & [u8]) -> Self { Self { battery_voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , cpu_temperature : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , flags : payload [8usize] , cell_voltages_length : u8 :: from_le_bytes (payload [9usize .. 9usize + 1usize] . try_into () . expect ("Wrong slice length")) , cell_voltages : payload [9usize .. payload . len ()] . chunks_exact (2usize) . into_iter () . map (| a | u16 :: from_le_bytes ((* a) . try_into () . expect ("Wrong slice length"))) . collect :: < Vec < u16 >> () , } } } impl MessageInfo for StateStruct { fn id () -> u16 { 9106u16 } fn name () -> & 'static str { "state" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the frequency to automatically output state messages."] # [doc = "# Arguments"] # [doc = "* `rate` \\[Hz\\] - Rate to stream `state` messages. 0~100000Hz"] pub async fn set_stream_rate (& self , rate : u32) -> Result < () , PingError > { let request = Messages :: SetStreamRate (SetStreamRateStruct { rate , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetStreamRateStruct :: id ()) . await } # [doc = "Get the undervoltage timeout"] pub async fn cell_timeout (& self) -> Result < CellTimeoutStruct , PingError > { self . request () . await } # [doc = "Get the over-current timeout"] pub async fn current_timeout (& self) -> Result < CurrentTimeoutStruct , PingError > { self . request () . await } # [doc = "get the maximum allowed battery current"] pub async fn current_max (& self) -> Result < CurrentMaxStruct , PingError > { self . request () . await } # [doc = "Get the over-temperature timeout"] pub async fn temperature_timeout (& self) -> Result < TemperatureTimeoutStruct , PingError > { self . request () . await } # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] # [doc = "# Arguments"] # [doc = "* `setting` - 0~999: x = 0~0.999"] pub async fn set_lpf_setting (& self , setting : u16) -> Result < () , PingError > { let request = Messages :: SetLpfSetting (SetLpfSettingStruct { setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSettingStruct :: id ()) . await } # [doc = "Set the under-voltage timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_cell_voltage_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageTimeout (SetCellVoltageTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageTimeoutStruct :: id ()) . await } # [doc = "Set the maximum allowed battery current"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centiampere\\] - The maximum allowed battery current 0~20000 = 0~200A"] pub async fn set_current_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentMax (SetCurrentMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentMaxStruct :: id ()) . await } # [doc = "the frequency to take adc samples and run the filter."] # [doc = "# Arguments"] # [doc = "* `sample_frequency` - sample frequency in Hz. 1~100000"] pub async fn set_lpf_sample_frequency (& self , sample_frequency : u32) -> Result < () , PingError > { let request = Messages :: SetLpfSampleFrequency (SetLpfSampleFrequencyStruct { sample_frequency , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSampleFrequencyStruct :: id ()) . await } # [doc = "Set the maximum allowed battery temperature"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centidegrees Centigrade\\] - The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] pub async fn set_temperature_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureMax (SetTemperatureMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureMaxStruct :: id ()) . await } # [doc = "Get the maximum allowed battery temperature"] pub async fn temperature_max (& self) -> Result < TemperatureMaxStruct , PingError > { self . request () . await } # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub async fn events (& self) -> Result < EventsStruct , PingError > { self . request () . await } # [doc = "Set the over-current timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_current_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentTimeout (SetCurrentTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentTimeoutStruct :: id ()) . await } # [doc = "Set the over-temperature timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_temperature_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureTimeout (SetTemperatureTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureTimeoutStruct :: id ()) . await } # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] # [doc = "# Arguments"] pub async fn erase_flash (& self ,) -> Result < () , PingError > { let request = Messages :: EraseFlash (EraseFlashStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Reset parameter configuration to default values."] # [doc = "# Arguments"] pub async fn reset_defaults (& self ,) -> Result < () , PingError > { let request = Messages :: ResetDefaults (ResetDefaultsStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "reboot the system"] # [doc = "# Arguments"] # [doc = "* `goto_bootloader` - 0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] pub async fn reboot (& self , goto_bootloader : u8) -> Result < () , PingError > { let request = Messages :: Reboot (RebootStruct { goto_bootloader , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Get the minimum allowed cell voltage"] pub async fn cell_voltage_min (& self) -> Result < CellVoltageMinStruct , PingError > { self . request () . await } # [doc = "Set the minimum allowed cell voltage"] # [doc = "# Arguments"] # [doc = "* `limit` \\[millivolt\\] - The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] pub async fn set_cell_voltage_minimum (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageMinimum (SetCellVoltageMinimumStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageMinimumStruct :: id ()) . await } # [doc = "Get the current state of the device"] pub async fn state (& self) -> Result < StateStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetStreamRate (..) => "set_stream_rate" , Messages :: CellTimeout (..) => "cell_timeout" , Messages :: CurrentTimeout (..) => "current_timeout" , Messages :: CurrentMax (..) => "current_max" , Messages :: TemperatureTimeout (..) => "temperature_timeout" , Messages :: SetLpfSetting (..) => "set_lpf_setting" , Messages :: SetCellVoltageTimeout (..) => "set_cell_voltage_timeout" , Messages :: SetCurrentMax (..) => "set_current_max" , Messages :: SetLpfSampleFrequency (..) => "set_lpf_sample_frequency" , Messages :: SetTemperatureMax (..) => "set_temperature_max" , Messages :: TemperatureMax (..) => "temperature_max" , Messages :: Events (..) => "events" , Messages :: SetCurrentTimeout (..) => "set_current_timeout" , Messages :: SetTemperatureTimeout (..) => "set_temperature_timeout" , Messages :: EraseFlash (..) => "erase_flash" , Messages :: ResetDefaults (..) => "reset_defaults" , Messages :: Reboot (..) => "reboot" , Messages :: CellVoltageMin (..) => "cell_voltage_min" , Messages :: SetCellVoltageMinimum (..) => "set_cell_voltage_minimum" , Messages :: State (..) => "state" , } } fn message_id (& self) -> u16 { match self { Messages :: SetStreamRate (..) => 9006u16 , Messages :: CellTimeout (..) => 9101u16 , Messages :: CurrentTimeout (..) => 9103u16 , Messages :: CurrentMax (..) => 9102u16 , Messages :: TemperatureTimeout (..) => 9105u16 , Messages :: SetLpfSetting (..) => 9008u16 , Messages :: SetCellVoltageTimeout (..) => 9001u16 , Messages :: SetCurrentMax (..) => 9002u16 , Messages :: SetLpfSampleFrequency (..) => 9007u16 , Messages :: SetTemperatureMax (..) => 9004u16 , Messages :: TemperatureMax (..) => 9104u16 , Messages :: Events (..) => 9107u16 , Messages :: SetCurrentTimeout (..) => 9003u16 , Messages :: SetTemperatureTimeout (..) => 9005u16 , Messages :: EraseFlash (..) => 9201u16 , Messages :: ResetDefaults (..) => 9202u16 , Messages :: Reboot (..) => 9200u16 , Messages :: CellVoltageMin (..) => 9100u16 , Messages :: SetCellVoltageMinimum (..) => 9000u16 , Messages :: State (..) => 9106u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_stream_rate" => Ok (9006u16) , "cell_timeout" => Ok (9101u16) , "current_timeout" => Ok (9103u16) , "current_max" => Ok (9102u16) , "temperature_timeout" => Ok (9105u16) , "set_lpf_setting" => Ok (9008u16) , "set_cell_voltage_timeout" => Ok (9001u16) , "set_current_max" => Ok (9002u16) , "set_lpf_sample_frequency" => Ok (9007u16) , "set_temperature_max" => Ok (9004u16) , "temperature_max" => Ok (9104u16) , "events" => Ok (9107u16) , "set_current_timeout" => Ok (9003u16) , "set_temperature_timeout" => Ok (9005u16) , "erase_flash" => Ok (9201u16) , "reset_defaults" => Ok (9202u16) , "reboot" => Ok (9200u16) , "cell_voltage_min" => Ok (9100u16) , "set_cell_voltage_minimum" => Ok (9000u16) , "state" => Ok (9106u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetStreamRate (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSampleFrequency (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Events (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: EraseFlash (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ResetDefaults (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reboot (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellVoltageMin (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageMinimum (content) => (content as & dyn SerializePayload) . serialize () , Messages :: State (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 9006u16 => Messages :: SetStreamRate (< SetStreamRateStruct as DeserializePayload > :: deserialize (payload)) , 9101u16 => Messages :: CellTimeout (< CellTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9103u16 => Messages :: CurrentTimeout (< CurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9102u16 => Messages :: CurrentMax (< CurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9105u16 => Messages :: TemperatureTimeout (< TemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9008u16 => Messages :: SetLpfSetting (< SetLpfSettingStruct as DeserializePayload > :: deserialize (payload)) , 9001u16 => Messages :: SetCellVoltageTimeout (< SetCellVoltageTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9002u16 => Messages :: SetCurrentMax (< SetCurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9007u16 => Messages :: SetLpfSampleFrequency (< SetLpfSampleFrequencyStruct as DeserializePayload > :: deserialize (payload)) , 9004u16 => Messages :: SetTemperatureMax (< SetTemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9104u16 => Messages :: TemperatureMax (< TemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9107u16 => Messages :: Events (< EventsStruct as DeserializePayload > :: deserialize (payload)) , 9003u16 => Messages :: SetCurrentTimeout (< SetCurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9005u16 => Messages :: SetTemperatureTimeout (< SetTemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9201u16 => Messages :: EraseFlash (< EraseFlashStruct as DeserializePayload > :: deserialize (payload)) , 9202u16 => Messages :: ResetDefaults (< ResetDefaultsStruct as DeserializePayload > :: deserialize (payload)) , 9200u16 => Messages :: Reboot (< RebootStruct as DeserializePayload > :: deserialize (payload)) , 9100u16 => Messages :: CellVoltageMin (< CellVoltageMinStruct as DeserializePayload > :: deserialize (payload)) , 9000u16 => Messages :: SetCellVoltageMinimum (< SetCellVoltageMinimumStruct as DeserializePayload > :: deserialize (payload)) , 9106u16 => Messages :: State (< StateStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetStreamRate (SetStreamRateStruct) , CellTimeout (CellTimeoutStruct) , CurrentTimeout (CurrentTimeoutStruct) , CurrentMax (CurrentMaxStruct) , TemperatureTimeout (TemperatureTimeoutStruct) , SetLpfSetting (SetLpfSettingStruct) , SetCellVoltageTimeout (SetCellVoltageTimeoutStruct) , SetCurrentMax (SetCurrentMaxStruct) , SetLpfSampleFrequency (SetLpfSampleFrequencyStruct) , SetTemperatureMax (SetTemperatureMaxStruct) , TemperatureMax (TemperatureMaxStruct) , Events (EventsStruct) , SetCurrentTimeout (SetCurrentTimeoutStruct) , SetTemperatureTimeout (SetTemperatureTimeoutStruct) , EraseFlash (EraseFlashStruct) , ResetDefaults (ResetDefaultsStruct) , Reboot (RebootStruct) , CellVoltageMin (CellVoltageMinStruct) , SetCellVoltageMinimum (SetCellVoltageMinimumStruct) , State (StateStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetStreamRate (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSampleFrequency (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Events (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: EraseFlash (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ResetDefaults (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reboot (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellVoltageMin (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageMinimum (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: State (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the frequency to automatically output state messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the frequency to automatically output state messages."] pub struct SetStreamRateStruct { # [doc = "Rate to stream `state` messages. 0~100000Hz"] # [cfg_attr (feature = "schemars" , schemars (description = "Rate to stream `state` messages. 0~100000Hz"))] pub rate : u32 , } impl SerializePayload for SetStreamRateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . rate . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetStreamRateStruct { fn deserialize (payload : & [u8]) -> Self { Self { rate : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetStreamRateStruct { fn id () -> u16 { 9006u16 } fn name () -> & 'static str { "set_stream_rate" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the undervoltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the undervoltage timeout"] pub struct CellTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CellTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellTimeoutStruct { fn id () -> u16 { 9101u16 } fn name () -> & 'static str { "cell_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-current timeout"] pub struct CurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentTimeoutStruct { fn id () -> u16 { 9103u16 } fn name () -> & 'static str { "current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "get the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "get the maximum allowed battery current"] pub struct CurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for CurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentMaxStruct { fn id () -> u16 { 9102u16 } fn name () -> & 'static str { "current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-temperature timeout"] pub struct TemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for TemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureTimeoutStruct { fn id () -> u16 { 9105u16 } fn name () -> & 'static str { "temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] pub struct SetLpfSettingStruct { # [doc = "0~999: x = 0~0.999"] # [cfg_attr (feature = "schemars" , schemars (description = "0~999: x = 0~0.999"))] pub setting : u16 , } impl SerializePayload for SetLpfSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { setting : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSettingStruct { fn id () -> u16 { 9008u16 } fn name () -> & 'static str { "set_lpf_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the under-voltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the under-voltage timeout"] pub struct SetCellVoltageTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCellVoltageTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageTimeoutStruct { fn id () -> u16 { 9001u16 } fn name () -> & 'static str { "set_cell_voltage_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery current"] pub struct SetCurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for SetCurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentMaxStruct { fn id () -> u16 { 9002u16 } fn name () -> & 'static str { "set_current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "the frequency to take adc samples and run the filter."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "the frequency to take adc samples and run the filter."] pub struct SetLpfSampleFrequencyStruct { # [doc = "sample frequency in Hz. 1~100000"] # [cfg_attr (feature = "schemars" , schemars (description = "sample frequency in Hz. 1~100000"))] pub sample_frequency : u32 , } impl SerializePayload for SetLpfSampleFrequencyStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . sample_frequency . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSampleFrequencyStruct { fn deserialize (payload : & [u8]) -> Self { Self { sample_frequency : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSampleFrequencyStruct { fn id () -> u16 { 9007u16 } fn name () -> & 'static str { "set_lpf_sample_frequency" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery temperature"] pub struct SetTemperatureMaxStruct { # [doc = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetTemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureMaxStruct { fn id () -> u16 { 9004u16 } fn name () -> & 'static str { "set_temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the maximum allowed battery temperature"] pub struct TemperatureMaxStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for TemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureMaxStruct { fn id () -> u16 { 9104u16 } fn name () -> & 'static str { "temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub struct EventsStruct { # [doc = "The number of under-voltage events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of under-voltage events"))] pub voltage : u16 , # [doc = "The number of over-current events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-current events"))] pub current : u16 , # [doc = "The number of over-temperature events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-temperature events"))] pub temperature : u16 , } impl SerializePayload for EventsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . current . to_le_bytes ()) ; buffer . extend_from_slice (& self . temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for EventsStruct { fn deserialize (payload : & [u8]) -> Self { Self { voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for EventsStruct { fn id () -> u16 { 9107u16 } fn name () -> & 'static str { "events" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-current timeout"] pub struct SetCurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentTimeoutStruct { fn id () -> u16 { 9003u16 } fn name () -> & 'static str { "set_current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-temperature timeout"] pub struct SetTemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetTemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureTimeoutStruct { fn id () -> u16 { 9005u16 } fn name () -> & 'static str { "set_temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] pub struct EraseFlashStruct { } impl SerializePayload for EraseFlashStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for EraseFlashStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for EraseFlashStruct { fn id () -> u16 { 9201u16 } fn name () -> & 'static str { "erase_flash" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset parameter configuration to default values."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset parameter configuration to default values."] pub struct ResetDefaultsStruct { } impl SerializePayload for ResetDefaultsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for ResetDefaultsStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for ResetDefaultsStruct { fn id () -> u16 { 9202u16 } fn name () -> & 'static str { "reset_defaults" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "reboot the system"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "reboot the system"] pub struct RebootStruct { # [doc = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"))] pub goto_bootloader : u8 , } impl SerializePayload for RebootStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . goto_bootloader . to_le_bytes ()) ; buffer } } impl DeserializePayload for RebootStruct { fn deserialize (payload : & [u8]) -> Self { Self { goto_bootloader : payload [0usize] . into () , } } } impl MessageInfo for RebootStruct { fn id () -> u16 { 9200u16 } fn name () -> & 'static str { "reboot" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the minimum allowed cell voltage"] pub struct CellVoltageMinStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for CellVoltageMinStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellVoltageMinStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellVoltageMinStruct { fn id () -> u16 { 9100u16 } fn name () -> & 'static str { "cell_voltage_min" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the minimum allowed cell voltage"] pub struct SetCellVoltageMinimumStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetCellVoltageMinimumStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageMinimumStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageMinimumStruct { fn id () -> u16 { 9000u16 } fn name () -> & 'static str { "set_cell_voltage_minimum" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the current state of the device"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the current state of the device"] pub struct StateStruct { # [doc = "The main battery voltage"] # [cfg_attr (feature = "schemars" , schemars (description = "The main battery voltage"))] pub battery_voltage : u16 , # [doc = "The current measurement"] # [cfg_attr (feature = "schemars" , schemars (description = "The current measurement"))] pub battery_current : u16 , # [doc = "The battery temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The battery temperature"))] pub battery_temperature : u16 , # [doc = "The cpu temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The cpu temperature"))] pub cpu_temperature : u16 , # [doc = "flags indicating if any of the configured limits are currently exceeded"] # [cfg_attr (feature = "schemars" , schemars (description = "flags indicating if any of the configured limits are currently exceeded"))] pub flags : u8 , # [doc = "Array containing cell voltages"] # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages_length : u8 , # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages : Vec < u16 > , } impl SerializePayload for StateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . battery_voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_current . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . cpu_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . flags . to_le_bytes ()) ; buffer . extend_from_slice (& self . cell_voltages_length . to_le_bytes ()) ; for value in self . cell_voltages . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for StateStruct { fn deserialize (payload : & [u8]) -> Self { Self { battery_voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , cpu_temperature : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , flags : payload [8usize] . into () , cell_voltages_length : u8 :: from_le_bytes (payload [9usize .. 9usize + 1usize] . try_into () . expect ("Wrong slice length")) , cell_voltages : payload [9usize .. payload . len ()] . chunks_exact (2usize) . into_iter () . map (| a | u16 :: from_le_bytes ((* a) . try_into () . expect ("Wrong slice length"))) . collect :: < Vec < u16 >> () , } } } impl MessageInfo for StateStruct { fn id () -> u16 { 9106u16 } fn name () -> & 'static str { "state" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the frequency to automatically output state messages."] # [doc = "# Arguments"] # [doc = "* `rate` \\[Hz\\] - Rate to stream `state` messages. 0~100000Hz"] pub async fn set_stream_rate (& self , rate : u32) -> Result < () , PingError > { let request = Messages :: SetStreamRate (SetStreamRateStruct { rate , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetStreamRateStruct :: id ()) . await } # [doc = "Get the undervoltage timeout"] pub async fn cell_timeout (& self) -> Result < CellTimeoutStruct , PingError > { self . request () . await } # [doc = "Get the over-current timeout"] pub async fn current_timeout (& self) -> Result < CurrentTimeoutStruct , PingError > { self . request () . await } # [doc = "get the maximum allowed battery current"] pub async fn current_max (& self) -> Result < CurrentMaxStruct , PingError > { self . request () . await } # [doc = "Get the over-temperature timeout"] pub async fn temperature_timeout (& self) -> Result < TemperatureTimeoutStruct , PingError > { self . request () . await } # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] # [doc = "# Arguments"] # [doc = "* `setting` - 0~999: x = 0~0.999"] pub async fn set_lpf_setting (& self , setting : u16) -> Result < () , PingError > { let request = Messages :: SetLpfSetting (SetLpfSettingStruct { setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSettingStruct :: id ()) . await } # [doc = "Set the under-voltage timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_cell_voltage_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageTimeout (SetCellVoltageTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageTimeoutStruct :: id ()) . await } # [doc = "Set the maximum allowed battery current"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centiampere\\] - The maximum allowed battery current 0~20000 = 0~200A"] pub async fn set_current_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentMax (SetCurrentMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentMaxStruct :: id ()) . await } # [doc = "the frequency to take adc samples and run the filter."] # [doc = "# Arguments"] # [doc = "* `sample_frequency` - sample frequency in Hz. 1~100000"] pub async fn set_lpf_sample_frequency (& self , sample_frequency : u32) -> Result < () , PingError > { let request = Messages :: SetLpfSampleFrequency (SetLpfSampleFrequencyStruct { sample_frequency , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSampleFrequencyStruct :: id ()) . await } # [doc = "Set the maximum allowed battery temperature"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centidegrees Centigrade\\] - The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] pub async fn set_temperature_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureMax (SetTemperatureMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureMaxStruct :: id ()) . await } # [doc = "Get the maximum allowed battery temperature"] pub async fn temperature_max (& self) -> Result < TemperatureMaxStruct , PingError > { self . request () . await } # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub async fn events (& self) -> Result < EventsStruct , PingError > { self . request () . await } # [doc = "Set the over-current timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_current_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentTimeout (SetCurrentTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentTimeoutStruct :: id ()) . await } # [doc = "Set the over-temperature timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_temperature_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureTimeout (SetTemperatureTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureTimeoutStruct :: id ()) . await } # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] # [doc = "# Arguments"] pub async fn erase_flash (& self ,) -> Result < () , PingError > { let request = Messages :: EraseFlash (EraseFlashStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Reset parameter configuration to default values."] # [doc = "# Arguments"] pub async fn reset_defaults (& self ,) -> Result < () , PingError > { let request = Messages :: ResetDefaults (ResetDefaultsStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "reboot the system"] # [doc = "# Arguments"] # [doc = "* `goto_bootloader` - 0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] pub async fn reboot (& self , goto_bootloader : u8) -> Result < () , PingError > { let request = Messages :: Reboot (RebootStruct { goto_bootloader , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Get the minimum allowed cell voltage"] pub async fn cell_voltage_min (& self) -> Result < CellVoltageMinStruct , PingError > { self . request () . await } # [doc = "Set the minimum allowed cell voltage"] # [doc = "# Arguments"] # [doc = "* `limit` \\[millivolt\\] - The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] pub async fn set_cell_voltage_minimum (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageMinimum (SetCellVoltageMinimumStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageMinimumStruct :: id ()) . await } # [doc = "Get the current state of the device"] pub async fn state (& self) -> Result < StateStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetStreamRate (..) => "set_stream_rate" , Messages :: CellTimeout (..) => "cell_timeout" , Messages :: CurrentTimeout (..) => "current_timeout" , Messages :: CurrentMax (..) => "current_max" , Messages :: TemperatureTimeout (..) => "temperature_timeout" , Messages :: SetLpfSetting (..) => "set_lpf_setting" , Messages :: SetCellVoltageTimeout (..) => "set_cell_voltage_timeout" , Messages :: SetCurrentMax (..) => "set_current_max" , Messages :: SetLpfSampleFrequency (..) => "set_lpf_sample_frequency" , Messages :: SetTemperatureMax (..) => "set_temperature_max" , Messages :: TemperatureMax (..) => "temperature_max" , Messages :: Events (..) => "events" , Messages :: SetCurrentTimeout (..) => "set_current_timeout" , Messages :: SetTemperatureTimeout (..) => "set_temperature_timeout" , Messages :: EraseFlash (..) => "erase_flash" , Messages :: ResetDefaults (..) => "reset_defaults" , Messages :: Reboot (..) => "reboot" , Messages :: CellVoltageMin (..) => "cell_voltage_min" , Messages :: SetCellVoltageMinimum (..) => "set_cell_voltage_minimum" , Messages :: State (..) => "state" , } } fn message_id (& self) -> u16 { match self { Messages :: SetStreamRate (..) => 9006u16 , Messages :: CellTimeout (..) => 9101u16 , Messages :: CurrentTimeout (..) => 9103u16 , Messages :: CurrentMax (..) => 9102u16 , Messages :: TemperatureTimeout (..) => 9105u16 , Messages :: SetLpfSetting (..) => 9008u16 , Messages :: SetCellVoltageTimeout (..) => 9001u16 , Messages :: SetCurrentMax (..) => 9002u16 , Messages :: SetLpfSampleFrequency (..) => 9007u16 , Messages :: SetTemperatureMax (..) => 9004u16 , Messages :: TemperatureMax (..) => 9104u16 , Messages :: Events (..) => 9107u16 , Messages :: SetCurrentTimeout (..) => 9003u16 , Messages :: SetTemperatureTimeout (..) => 9005u16 , Messages :: EraseFlash (..) => 9201u16 , Messages :: ResetDefaults (..) => 9202u16 , Messages :: Reboot (..) => 9200u16 , Messages :: CellVoltageMin (..) => 9100u16 , Messages :: SetCellVoltageMinimum (..) => 9000u16 , Messages :: State (..) => 9106u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_stream_rate" => Ok (9006u16) , "cell_timeout" => Ok (9101u16) , "current_timeout" => Ok (9103u16) , "current_max" => Ok (9102u16) , "temperature_timeout" => Ok (9105u16) , "set_lpf_setting" => Ok (9008u16) , "set_cell_voltage_timeout" => Ok (9001u16) , "set_current_max" => Ok (9002u16) , "set_lpf_sample_frequency" => Ok (9007u16) , "set_temperature_max" => Ok (9004u16) , "temperature_max" => Ok (9104u16) , "events" => Ok (9107u16) , "set_current_timeout" => Ok (9003u16) , "set_temperature_timeout" => Ok (9005u16) , "erase_flash" => Ok (9201u16) , "reset_defaults" => Ok (9202u16) , "reboot" => Ok (9200u16) , "cell_voltage_min" => Ok (9100u16) , "set_cell_voltage_minimum" => Ok (9000u16) , "state" => Ok (9106u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetStreamRate (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSampleFrequency (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Events (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: EraseFlash (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ResetDefaults (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reboot (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellVoltageMin (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageMinimum (content) => (content as & dyn SerializePayload) . serialize () , Messages :: State (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 9006u16 => Messages :: SetStreamRate (< SetStreamRateStruct as DeserializePayload > :: deserialize (payload)) , 9101u16 => Messages :: CellTimeout (< CellTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9103u16 => Messages :: CurrentTimeout (< CurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9102u16 => Messages :: CurrentMax (< CurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9105u16 => Messages :: TemperatureTimeout (< TemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9008u16 => Messages :: SetLpfSetting (< SetLpfSettingStruct as DeserializePayload > :: deserialize (payload)) , 9001u16 => Messages :: SetCellVoltageTimeout (< SetCellVoltageTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9002u16 => Messages :: SetCurrentMax (< SetCurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9007u16 => Messages :: SetLpfSampleFrequency (< SetLpfSampleFrequencyStruct as DeserializePayload > :: deserialize (payload)) , 9004u16 => Messages :: SetTemperatureMax (< SetTemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9104u16 => Messages :: TemperatureMax (< TemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9107u16 => Messages :: Events (< EventsStruct as DeserializePayload > :: deserialize (payload)) , 9003u16 => Messages :: SetCurrentTimeout (< SetCurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9005u16 => Messages :: SetTemperatureTimeout (< SetTemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9201u16 => Messages :: EraseFlash (< EraseFlashStruct as DeserializePayload > :: deserialize (payload)) , 9202u16 => Messages :: ResetDefaults (< ResetDefaultsStruct as DeserializePayload > :: deserialize (payload)) , 9200u16 => Messages :: Reboot (< RebootStruct as DeserializePayload > :: deserialize (payload)) , 9100u16 => Messages :: CellVoltageMin (< CellVoltageMinStruct as DeserializePayload > :: deserialize (payload)) , 9000u16 => Messages :: SetCellVoltageMinimum (< SetCellVoltageMinimumStruct as DeserializePayload > :: deserialize (payload)) , 9106u16 => Messages :: State (< StateStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetStreamRate (SetStreamRateStruct) , CellTimeout (CellTimeoutStruct) , CurrentTimeout (CurrentTimeoutStruct) , CurrentMax (CurrentMaxStruct) , TemperatureTimeout (TemperatureTimeoutStruct) , SetLpfSetting (SetLpfSettingStruct) , SetCellVoltageTimeout (SetCellVoltageTimeoutStruct) , SetCurrentMax (SetCurrentMaxStruct) , SetLpfSampleFrequency (SetLpfSampleFrequencyStruct) , SetTemperatureMax (SetTemperatureMaxStruct) , TemperatureMax (TemperatureMaxStruct) , Events (EventsStruct) , SetCurrentTimeout (SetCurrentTimeoutStruct) , SetTemperatureTimeout (SetTemperatureTimeoutStruct) , EraseFlash (EraseFlashStruct) , ResetDefaults (ResetDefaultsStruct) , Reboot (RebootStruct) , CellVoltageMin (CellVoltageMinStruct) , SetCellVoltageMinimum (SetCellVoltageMinimumStruct) , State (StateStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetStreamRate (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetLpfSampleFrequency (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TemperatureMax (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Events (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCurrentTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetTemperatureTimeout (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: EraseFlash (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ResetDefaults (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Reboot (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: CellVoltageMin (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetCellVoltageMinimum (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: State (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the frequency to automatically output state messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the frequency to automatically output state messages."] pub struct SetStreamRateStruct { # [doc = "Rate to stream `state` messages. 0~100000Hz"] # [cfg_attr (feature = "schemars" , schemars (description = "Rate to stream `state` messages. 0~100000Hz"))] pub rate : u32 , } impl SerializePayload for SetStreamRateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . rate . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetStreamRateStruct { fn deserialize (payload : & [u8]) -> Self { Self { rate : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetStreamRateStruct { fn id () -> u16 { 9006u16 } fn name () -> & 'static str { "set_stream_rate" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the undervoltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the undervoltage timeout"] pub struct CellTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CellTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellTimeoutStruct { fn id () -> u16 { 9101u16 } fn name () -> & 'static str { "cell_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-current timeout"] pub struct CurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for CurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentTimeoutStruct { fn id () -> u16 { 9103u16 } fn name () -> & 'static str { "current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "get the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "get the maximum allowed battery current"] pub struct CurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for CurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CurrentMaxStruct { fn id () -> u16 { 9102u16 } fn name () -> & 'static str { "current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the over-temperature timeout"] pub struct TemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for TemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureTimeoutStruct { fn id () -> u16 { 9105u16 } fn name () -> & 'static str { "temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] pub struct SetLpfSettingStruct { # [doc = "0~999: x = 0~0.999"] # [cfg_attr (feature = "schemars" , schemars (description = "0~999: x = 0~0.999"))] pub setting : u16 , } impl SerializePayload for SetLpfSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { setting : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSettingStruct { fn id () -> u16 { 9008u16 } fn name () -> & 'static str { "set_lpf_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the under-voltage timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the under-voltage timeout"] pub struct SetCellVoltageTimeoutStruct { # [doc = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCellVoltageTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageTimeoutStruct { fn id () -> u16 { 9001u16 } fn name () -> & 'static str { "set_cell_voltage_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery current"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery current"] pub struct SetCurrentMaxStruct { # [doc = "The maximum allowed battery current 0~20000 = 0~200A"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum allowed battery current 0~20000 = 0~200A"))] pub limit : u16 , } impl SerializePayload for SetCurrentMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentMaxStruct { fn id () -> u16 { 9002u16 } fn name () -> & 'static str { "set_current_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "the frequency to take adc samples and run the filter."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "the frequency to take adc samples and run the filter."] pub struct SetLpfSampleFrequencyStruct { # [doc = "sample frequency in Hz. 1~100000"] # [cfg_attr (feature = "schemars" , schemars (description = "sample frequency in Hz. 1~100000"))] pub sample_frequency : u32 , } impl SerializePayload for SetLpfSampleFrequencyStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . sample_frequency . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetLpfSampleFrequencyStruct { fn deserialize (payload : & [u8]) -> Self { Self { sample_frequency : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetLpfSampleFrequencyStruct { fn id () -> u16 { 9007u16 } fn name () -> & 'static str { "set_lpf_sample_frequency" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the maximum allowed battery temperature"] pub struct SetTemperatureMaxStruct { # [doc = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetTemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureMaxStruct { fn id () -> u16 { 9004u16 } fn name () -> & 'static str { "set_temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the maximum allowed battery temperature"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the maximum allowed battery temperature"] pub struct TemperatureMaxStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for TemperatureMaxStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for TemperatureMaxStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TemperatureMaxStruct { fn id () -> u16 { 9104u16 } fn name () -> & 'static str { "temperature_max" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub struct EventsStruct { # [doc = "The number of under-voltage events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of under-voltage events"))] pub voltage : u16 , # [doc = "The number of over-current events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-current events"))] pub current : u16 , # [doc = "The number of over-temperature events"] # [cfg_attr (feature = "schemars" , schemars (description = "The number of over-temperature events"))] pub temperature : u16 , } impl SerializePayload for EventsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . current . to_le_bytes ()) ; buffer . extend_from_slice (& self . temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for EventsStruct { fn deserialize (payload : & [u8]) -> Self { Self { voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for EventsStruct { fn id () -> u16 { 9107u16 } fn name () -> & 'static str { "events" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-current timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-current timeout"] pub struct SetCurrentTimeoutStruct { # [doc = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetCurrentTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCurrentTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCurrentTimeoutStruct { fn id () -> u16 { 9003u16 } fn name () -> & 'static str { "set_current_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the over-temperature timeout"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the over-temperature timeout"] pub struct SetTemperatureTimeoutStruct { # [doc = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] # [cfg_attr (feature = "schemars" , schemars (description = "If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"))] pub timeout : u16 , } impl SerializePayload for SetTemperatureTimeoutStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . timeout . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetTemperatureTimeoutStruct { fn deserialize (payload : & [u8]) -> Self { Self { timeout : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetTemperatureTimeoutStruct { fn id () -> u16 { 9005u16 } fn name () -> & 'static str { "set_temperature_timeout" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] pub struct EraseFlashStruct { } impl SerializePayload for EraseFlashStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for EraseFlashStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for EraseFlashStruct { fn id () -> u16 { 9201u16 } fn name () -> & 'static str { "erase_flash" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Reset parameter configuration to default values."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Reset parameter configuration to default values."] pub struct ResetDefaultsStruct { } impl SerializePayload for ResetDefaultsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for ResetDefaultsStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for ResetDefaultsStruct { fn id () -> u16 { 9202u16 } fn name () -> & 'static str { "reset_defaults" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "reboot the system"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "reboot the system"] pub struct RebootStruct { # [doc = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] # [cfg_attr (feature = "schemars" , schemars (description = "0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"))] pub goto_bootloader : u8 , } impl SerializePayload for RebootStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . goto_bootloader . to_le_bytes ()) ; buffer } } impl DeserializePayload for RebootStruct { fn deserialize (payload : & [u8]) -> Self { Self { goto_bootloader : payload [0usize] . into () , } } } impl MessageInfo for RebootStruct { fn id () -> u16 { 9200u16 } fn name () -> & 'static str { "reboot" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the minimum allowed cell voltage"] pub struct CellVoltageMinStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for CellVoltageMinStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for CellVoltageMinStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for CellVoltageMinStruct { fn id () -> u16 { 9100u16 } fn name () -> & 'static str { "cell_voltage_min" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the minimum allowed cell voltage"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the minimum allowed cell voltage"] pub struct SetCellVoltageMinimumStruct { # [doc = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum voltage allowed for any individual cell. 0~5000: 0~5V"))] pub limit : u16 , } impl SerializePayload for SetCellVoltageMinimumStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . limit . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetCellVoltageMinimumStruct { fn deserialize (payload : & [u8]) -> Self { Self { limit : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetCellVoltageMinimumStruct { fn id () -> u16 { 9000u16 } fn name () -> & 'static str { "set_cell_voltage_minimum" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the current state of the device"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the current state of the device"] pub struct StateStruct { # [doc = "The main battery voltage"] # [cfg_attr (feature = "schemars" , schemars (description = "The main battery voltage"))] pub battery_voltage : u16 , # [doc = "The current measurement"] # [cfg_attr (feature = "schemars" , schemars (description = "The current measurement"))] pub battery_current : u16 , # [doc = "The battery temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The battery temperature"))] pub battery_temperature : u16 , # [doc = "The cpu temperature"] # [cfg_attr (feature = "schemars" , schemars (description = "The cpu temperature"))] pub cpu_temperature : u16 , # [doc = "flags indicating if any of the configured limits are currently exceeded"] # [cfg_attr (feature = "schemars" , schemars (description = "flags indicating if any of the configured limits are currently exceeded"))] pub flags : u8 , # [doc = "Array containing cell voltages"] # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages_length : u8 , # [cfg_attr (feature = "schemars" , schemars (description = "Array containing cell voltages"))] pub cell_voltages : Vec < u16 > , } impl SerializePayload for StateStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . battery_voltage . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_current . to_le_bytes ()) ; buffer . extend_from_slice (& self . battery_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . cpu_temperature . to_le_bytes ()) ; buffer . extend_from_slice (& self . flags . to_le_bytes ()) ; buffer . extend_from_slice (& self . cell_voltages_length . to_le_bytes ()) ; for value in self . cell_voltages . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for StateStruct { fn deserialize (payload : & [u8]) -> Self { Self { battery_voltage : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_current : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , battery_temperature : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , cpu_temperature : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , flags : <u8 as Into<_>>::into(payload [8usize]) , cell_voltages_length : u8 :: from_le_bytes (payload [9usize .. 9usize + 1usize] . try_into () . expect ("Wrong slice length")) , cell_voltages : payload [9usize .. payload . len ()] . chunks_exact (2usize) . into_iter () . map (| a | u16 :: from_le_bytes ((* a) . try_into () . expect ("Wrong slice length"))) . collect :: < Vec < u16 >> () , } } } impl MessageInfo for StateStruct { fn id () -> u16 { 9106u16 } fn name () -> & 'static str { "state" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the frequency to automatically output state messages."] # [doc = "# Arguments"] # [doc = "* `rate` \\[Hz\\] - Rate to stream `state` messages. 0~100000Hz"] pub async fn set_stream_rate (& self , rate : u32) -> Result < () , PingError > { let request = Messages :: SetStreamRate (SetStreamRateStruct { rate , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetStreamRateStruct :: id ()) . await } # [doc = "Get the undervoltage timeout"] pub async fn cell_timeout (& self) -> Result < CellTimeoutStruct , PingError > { self . request () . await } # [doc = "Get the over-current timeout"] pub async fn current_timeout (& self) -> Result < CurrentTimeoutStruct , PingError > { self . request () . await } # [doc = "get the maximum allowed battery current"] pub async fn current_max (& self) -> Result < CurrentMaxStruct , PingError > { self . request () . await } # [doc = "Get the over-temperature timeout"] pub async fn temperature_timeout (& self) -> Result < TemperatureTimeoutStruct , PingError > { self . request () . await } # [doc = "Low pass filter setting. This value represents x in the equation `value = value * x + sample * (1-x)`. 0.0 = no filtering, 0.99 = heavy filtering."] # [doc = "# Arguments"] # [doc = "* `setting` - 0~999: x = 0~0.999"] pub async fn set_lpf_setting (& self , setting : u16) -> Result < () , PingError > { let request = Messages :: SetLpfSetting (SetLpfSettingStruct { setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSettingStruct :: id ()) . await } # [doc = "Set the under-voltage timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If an individual cell exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_cell_voltage_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageTimeout (SetCellVoltageTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageTimeoutStruct :: id ()) . await } # [doc = "Set the maximum allowed battery current"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centiampere\\] - The maximum allowed battery current 0~20000 = 0~200A"] pub async fn set_current_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentMax (SetCurrentMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentMaxStruct :: id ()) . await } # [doc = "the frequency to take adc samples and run the filter."] # [doc = "# Arguments"] # [doc = "* `sample_frequency` - sample frequency in Hz. 1~100000"] pub async fn set_lpf_sample_frequency (& self , sample_frequency : u32) -> Result < () , PingError > { let request = Messages :: SetLpfSampleFrequency (SetLpfSampleFrequencyStruct { sample_frequency , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetLpfSampleFrequencyStruct :: id ()) . await } # [doc = "Set the maximum allowed battery temperature"] # [doc = "# Arguments"] # [doc = "* `limit` \\[centidegrees Centigrade\\] - The maximum temperature allowed at the thermistor probe installed on the battery. 0~5000: 0~5V"] pub async fn set_temperature_max (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureMax (SetTemperatureMaxStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureMaxStruct :: id ()) . await } # [doc = "Get the maximum allowed battery temperature"] pub async fn temperature_max (& self) -> Result < TemperatureMaxStruct , PingError > { self . request () . await } # [doc = "A record of events causing a power lock-out. These numbers are non-volatile and reset only with the erase_flash control message."] pub async fn events (& self) -> Result < EventsStruct , PingError > { self . request () . await } # [doc = "Set the over-current timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery current exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_current_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetCurrentTimeout (SetCurrentTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCurrentTimeoutStruct :: id ()) . await } # [doc = "Set the over-temperature timeout"] # [doc = "# Arguments"] # [doc = "* `timeout` \\[millisecond\\] - If the battery temperature exceeds the configured limit for this duration of time, the power will be locked-out"] pub async fn set_temperature_timeout (& self , timeout : u16) -> Result < () , PingError > { let request = Messages :: SetTemperatureTimeout (SetTemperatureTimeoutStruct { timeout , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetTemperatureTimeoutStruct :: id ()) . await } # [doc = "Erase flash, including parameter configuration and event counters. The mcu has a limited number of write/erase cycles (1k)!"] # [doc = "# Arguments"] pub async fn erase_flash (& self ,) -> Result < () , PingError > { let request = Messages :: EraseFlash (EraseFlashStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Reset parameter configuration to default values."] # [doc = "# Arguments"] pub async fn reset_defaults (& self ,) -> Result < () , PingError > { let request = Messages :: ResetDefaults (ResetDefaultsStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "reboot the system"] # [doc = "# Arguments"] # [doc = "* `goto_bootloader` - 0 = normal reboot, run main application after reboot 1 = hold the device in bootloader after reboot"] pub async fn reboot (& self , goto_bootloader : u8) -> Result < () , PingError > { let request = Messages :: Reboot (RebootStruct { goto_bootloader , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Get the minimum allowed cell voltage"] pub async fn cell_voltage_min (& self) -> Result < CellVoltageMinStruct , PingError > { self . request () . await } # [doc = "Set the minimum allowed cell voltage"] # [doc = "# Arguments"] # [doc = "* `limit` \\[millivolt\\] - The minimum voltage allowed for any individual cell. 0~5000: 0~5V"] pub async fn set_cell_voltage_minimum (& self , limit : u16) -> Result < () , PingError > { let request = Messages :: SetCellVoltageMinimum (SetCellVoltageMinimumStruct { limit , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetCellVoltageMinimumStruct :: id ()) . await } # [doc = "Get the current state of the device"] pub async fn state (& self) -> Result < StateStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetStreamRate (..) => "set_stream_rate" , Messages :: CellTimeout (..) => "cell_timeout" , Messages :: CurrentTimeout (..) => "current_timeout" , Messages :: CurrentMax (..) => "current_max" , Messages :: TemperatureTimeout (..) => "temperature_timeout" , Messages :: SetLpfSetting (..) => "set_lpf_setting" , Messages :: SetCellVoltageTimeout (..) => "set_cell_voltage_timeout" , Messages :: SetCurrentMax (..) => "set_current_max" , Messages :: SetLpfSampleFrequency (..) => "set_lpf_sample_frequency" , Messages :: SetTemperatureMax (..) => "set_temperature_max" , Messages :: TemperatureMax (..) => "temperature_max" , Messages :: Events (..) => "events" , Messages :: SetCurrentTimeout (..) => "set_current_timeout" , Messages :: SetTemperatureTimeout (..) => "set_temperature_timeout" , Messages :: EraseFlash (..) => "erase_flash" , Messages :: ResetDefaults (..) => "reset_defaults" , Messages :: Reboot (..) => "reboot" , Messages :: CellVoltageMin (..) => "cell_voltage_min" , Messages :: SetCellVoltageMinimum (..) => "set_cell_voltage_minimum" , Messages :: State (..) => "state" , } } fn message_id (& self) -> u16 { match self { Messages :: SetStreamRate (..) => 9006u16 , Messages :: CellTimeout (..) => 9101u16 , Messages :: CurrentTimeout (..) => 9103u16 , Messages :: CurrentMax (..) => 9102u16 , Messages :: TemperatureTimeout (..) => 9105u16 , Messages :: SetLpfSetting (..) => 9008u16 , Messages :: SetCellVoltageTimeout (..) => 9001u16 , Messages :: SetCurrentMax (..) => 9002u16 , Messages :: SetLpfSampleFrequency (..) => 9007u16 , Messages :: SetTemperatureMax (..) => 9004u16 , Messages :: TemperatureMax (..) => 9104u16 , Messages :: Events (..) => 9107u16 , Messages :: SetCurrentTimeout (..) => 9003u16 , Messages :: SetTemperatureTimeout (..) => 9005u16 , Messages :: EraseFlash (..) => 9201u16 , Messages :: ResetDefaults (..) => 9202u16 , Messages :: Reboot (..) => 9200u16 , Messages :: CellVoltageMin (..) => 9100u16 , Messages :: SetCellVoltageMinimum (..) => 9000u16 , Messages :: State (..) => 9106u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_stream_rate" => Ok (9006u16) , "cell_timeout" => Ok (9101u16) , "current_timeout" => Ok (9103u16) , "current_max" => Ok (9102u16) , "temperature_timeout" => Ok (9105u16) , "set_lpf_setting" => Ok (9008u16) , "set_cell_voltage_timeout" => Ok (9001u16) , "set_current_max" => Ok (9002u16) , "set_lpf_sample_frequency" => Ok (9007u16) , "set_temperature_max" => Ok (9004u16) , "temperature_max" => Ok (9104u16) , "events" => Ok (9107u16) , "set_current_timeout" => Ok (9003u16) , "set_temperature_timeout" => Ok (9005u16) , "erase_flash" => Ok (9201u16) , "reset_defaults" => Ok (9202u16) , "reboot" => Ok (9200u16) , "cell_voltage_min" => Ok (9100u16) , "set_cell_voltage_minimum" => Ok (9000u16) , "state" => Ok (9106u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetStreamRate (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetLpfSampleFrequency (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TemperatureMax (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Events (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCurrentTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetTemperatureTimeout (content) => (content as & dyn SerializePayload) . serialize () , Messages :: EraseFlash (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ResetDefaults (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Reboot (content) => (content as & dyn SerializePayload) . serialize () , Messages :: CellVoltageMin (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetCellVoltageMinimum (content) => (content as & dyn SerializePayload) . serialize () , Messages :: State (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 9006u16 => Messages :: SetStreamRate (< SetStreamRateStruct as DeserializePayload > :: deserialize (payload)) , 9101u16 => Messages :: CellTimeout (< CellTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9103u16 => Messages :: CurrentTimeout (< CurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9102u16 => Messages :: CurrentMax (< CurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9105u16 => Messages :: TemperatureTimeout (< TemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9008u16 => Messages :: SetLpfSetting (< SetLpfSettingStruct as DeserializePayload > :: deserialize (payload)) , 9001u16 => Messages :: SetCellVoltageTimeout (< SetCellVoltageTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9002u16 => Messages :: SetCurrentMax (< SetCurrentMaxStruct as DeserializePayload > :: deserialize (payload)) , 9007u16 => Messages :: SetLpfSampleFrequency (< SetLpfSampleFrequencyStruct as DeserializePayload > :: deserialize (payload)) , 9004u16 => Messages :: SetTemperatureMax (< SetTemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9104u16 => Messages :: TemperatureMax (< TemperatureMaxStruct as DeserializePayload > :: deserialize (payload)) , 9107u16 => Messages :: Events (< EventsStruct as DeserializePayload > :: deserialize (payload)) , 9003u16 => Messages :: SetCurrentTimeout (< SetCurrentTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9005u16 => Messages :: SetTemperatureTimeout (< SetTemperatureTimeoutStruct as DeserializePayload > :: deserialize (payload)) , 9201u16 => Messages :: EraseFlash (< EraseFlashStruct as DeserializePayload > :: deserialize (payload)) , 9202u16 => Messages :: ResetDefaults (< ResetDefaultsStruct as DeserializePayload > :: deserialize (payload)) , 9200u16 => Messages :: Reboot (< RebootStruct as DeserializePayload > :: deserialize (payload)) , 9100u16 => Messages :: CellVoltageMin (< CellVoltageMinStruct as DeserializePayload > :: deserialize (payload)) , 9000u16 => Messages :: SetCellVoltageMinimum (< SetCellVoltageMinimumStruct as DeserializePayload > :: deserialize (payload)) , 9106u16 => Messages :: State (< StateStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/omniscan450.rs:1:8012
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...nto () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserv...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : <u8 as Into<_>>::into(payload [32usize]) , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/omniscan450.rs:1:8055
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...nable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserv...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : <u8 as Into<_>>::into(payload [33usize]) , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/omniscan450.rs:1:8098
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } ...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : <u8 as Into<_>>::into(payload [34usize]) , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/omniscan450.rs:1:8141
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { f...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : <u8 as Into<_>>::into(payload [35usize]) , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/omniscan450.rs:1:15108
[INFO] [stdout]   |
[INFO] [stdout] 1 | ... expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_du...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : <u8 as Into<_>>::into(payload [26usize]) , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/omniscan450.rs:1:15149
[INFO] [stdout]   |
[INFO] [stdout] 1 | ..._number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payloa...
[INFO] [stdout]   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : payload [27usize] . into () , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { JsonWrapper (JsonWrapperStruct) , OsPingParams (OsPingParamsStruct) , OsMonoProfile (OsMonoProfileStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: JsonWrapper (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsPingParams (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OsMonoProfile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct JsonWrapperStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub string : String , } impl SerializePayload for JsonWrapperStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . string . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for JsonWrapperStruct { fn deserialize (payload : & [u8]) -> Self { Self { string : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for JsonWrapperStruct { fn id () -> u16 { 10u16 } fn name () -> & 'static str { "JSON_WRAPPER" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "No documentation provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "No documentation provided."] pub struct OsPingParamsStruct { # [doc = "Start of ping range, set to 0."] # [cfg_attr (feature = "schemars" , schemars (description = "Start of ping range, set to 0."))] pub start_mm : u32 , # [doc = "Length of the returned profile, end of range = start_mm + length_mm."] # [cfg_attr (feature = "schemars" , schemars (description = "Length of the returned profile, end of range = start_mm + length_mm."))] pub length_mm : u32 , # [doc = "Set value to limit ping rate, normally set to 0 for best ping rate."] # [cfg_attr (feature = "schemars" , schemars (description = "Set value to limit ping rate, normally set to 0 for best ping rate."))] pub msec_per_ping : u32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_1 : f32 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_2 : f32 , # [doc = "% of total ping time for current range, 0.002 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "% of total ping time for current range, 0.002 typical."))] pub pulse_len_percent : f32 , # [doc = "0.0015 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "0.0015 typical."))] pub filter_duration_percent : f32 , # [doc = "Set to -1 for auto gain, otherwise 0-7 sets gain."] # [cfg_attr (feature = "schemars" , schemars (description = "Set to -1 for auto gain, otherwise 0-7 sets gain."))] pub gain_index : i16 , # [doc = "Number of signal data points in resulting profile (200-1200), 600 typical."] # [cfg_attr (feature = "schemars" , schemars (description = "Number of signal data points in resulting profile (200-1200), 600 typical."))] pub num_results : u16 , # [doc = "1 or 0 to enable or disable pinging."] # [cfg_attr (feature = "schemars" , schemars (description = "1 or 0 to enable or disable pinging."))] pub enable : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_3 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_4 : u8 , # [doc = "Set to 0"] # [cfg_attr (feature = "schemars" , schemars (description = "Set to 0"))] pub reserved_5 : u8 , } impl SerializePayload for OsPingParamsStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . msec_per_ping . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_1 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_2 . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_len_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . filter_duration_percent . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . enable . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_3 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_4 . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for OsPingParamsStruct { fn deserialize (payload : & [u8]) -> Self { Self { start_mm : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , msec_per_ping : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_1 : f32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , reserved_2 : f32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , pulse_len_percent : f32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , filter_duration_percent : f32 :: from_le_bytes (payload [24usize .. 24usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : i16 :: from_le_bytes (payload [28usize .. 28usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [30usize .. 30usize + 2usize] . try_into () . expect ("Wrong slice length")) , enable : payload [32usize] . into () , reserved_3 : payload [33usize] . into () , reserved_4 : payload [34usize] . into () , reserved_5 : payload [35usize] . into () , } } } impl MessageInfo for OsPingParamsStruct { fn id () -> u16 { 2197u16 } fn name () -> & 'static str { "os_ping_params" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub struct OsMonoProfileStruct { # [doc = "sequentially assigned from 0 at power up"] # [cfg_attr (feature = "schemars" , schemars (description = "sequentially assigned from 0 at power up"))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub start_mm : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub length_mm : u32 , # [doc = "msec since power up at time of ping"] # [cfg_attr (feature = "schemars" , schemars (description = "msec since power up at time of ping"))] pub timestamp_ms : u32 , # [doc = "Frequency of acoustic signal"] # [cfg_attr (feature = "schemars" , schemars (description = "Frequency of acoustic signal"))] pub ping_hz : u32 , # [doc = "0-7"] # [cfg_attr (feature = "schemars" , schemars (description = "0-7"))] pub gain_index : u16 , # [doc = "length of pwr_results array"] # [cfg_attr (feature = "schemars" , schemars (description = "length of pwr_results array"))] pub num_results : u16 , # [doc = "speed of sound, decimeters/sec"] # [cfg_attr (feature = "schemars" , schemars (description = "speed of sound, decimeters/sec"))] pub sos_dmps : u16 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub channel_number : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub reserved : u8 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub pulse_duration_sec : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub analog_gain : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub max_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub min_pwr_db : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub transducer_heading_deg : f32 , # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub vehicle_heading_deg : f32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range. power results scaled from min_pwr_db to max_pwr_db"))] pub pwr_results : String , } impl SerializePayload for OsMonoProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . start_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . length_mm . to_le_bytes ()) ; buffer . extend_from_slice (& self . timestamp_ms . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_hz . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_index . to_le_bytes ()) ; buffer . extend_from_slice (& self . num_results . to_le_bytes ()) ; buffer . extend_from_slice (& self . sos_dmps . to_le_bytes ()) ; buffer . extend_from_slice (& self . channel_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer . extend_from_slice (& self . pulse_duration_sec . to_le_bytes ()) ; buffer . extend_from_slice (& self . analog_gain . to_le_bytes ()) ; buffer . extend_from_slice (& self . max_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . min_pwr_db . to_le_bytes ()) ; buffer . extend_from_slice (& self . transducer_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (& self . vehicle_heading_deg . to_le_bytes ()) ; buffer . extend_from_slice (self . pwr_results . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for OsMonoProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_number : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , start_mm : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , length_mm : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , timestamp_ms : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , ping_hz : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_index : u16 :: from_le_bytes (payload [20usize .. 20usize + 2usize] . try_into () . expect ("Wrong slice length")) , num_results : u16 :: from_le_bytes (payload [22usize .. 22usize + 2usize] . try_into () . expect ("Wrong slice length")) , sos_dmps : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , channel_number : payload [26usize] . into () , reserved : <u8 as Into<_>>::into(payload [27usize]) , pulse_duration_sec : f32 :: from_le_bytes (payload [28usize .. 28usize + 4usize] . try_into () . expect ("Wrong slice length")) , analog_gain : f32 :: from_le_bytes (payload [32usize .. 32usize + 4usize] . try_into () . expect ("Wrong slice length")) , max_pwr_db : f32 :: from_le_bytes (payload [36usize .. 36usize + 4usize] . try_into () . expect ("Wrong slice length")) , min_pwr_db : f32 :: from_le_bytes (payload [40usize .. 40usize + 4usize] . try_into () . expect ("Wrong slice length")) , transducer_heading_deg : f32 :: from_le_bytes (payload [44usize .. 44usize + 4usize] . try_into () . expect ("Wrong slice length")) , vehicle_heading_deg : f32 :: from_le_bytes (payload [48usize .. 48usize + 4usize] . try_into () . expect ("Wrong slice length")) , pwr_results : String :: from_utf8 (payload [52usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for OsMonoProfileStruct { fn id () -> u16 { 2198u16 } fn name () -> & 'static str { "os_mono_profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "No documentation provided."] # [doc = "# Arguments"] # [doc = "* `start_mm` \\[mm\\] - Start of ping range, set to 0."] # [doc = "* `length_mm` \\[mm\\] - Length of the returned profile, end of range = start_mm + length_mm."] # [doc = "* `msec_per_ping` \\[msec\\] - Set value to limit ping rate, normally set to 0 for best ping rate."] # [doc = "* `reserved_1` - Set to 0"] # [doc = "* `reserved_2` - Set to 0"] # [doc = "* `pulse_len_percent` - % of total ping time for current range, 0.002 typical."] # [doc = "* `filter_duration_percent` - 0.0015 typical."] # [doc = "* `gain_index` - Set to -1 for auto gain, otherwise 0-7 sets gain."] # [doc = "* `num_results` - Number of signal data points in resulting profile (200-1200), 600 typical."] # [doc = "* `enable` - 1 or 0 to enable or disable pinging."] # [doc = "* `reserved_3` - Set to 0"] # [doc = "* `reserved_4` - Set to 0"] # [doc = "* `reserved_5` - Set to 0"] pub async fn os_ping_params (& self , start_mm : u32 , length_mm : u32 , msec_per_ping : u32 , reserved_1 : f32 , reserved_2 : f32 , pulse_len_percent : f32 , filter_duration_percent : f32 , gain_index : i16 , num_results : u16 , enable : u8 , reserved_3 : u8 , reserved_4 : u8 , reserved_5 : u8) -> Result < () , PingError > { let request = Messages :: OsPingParams (OsPingParamsStruct { start_mm , length_mm , msec_per_ping , reserved_1 , reserved_2 , pulse_len_percent , filter_duration_percent , gain_index , num_results , enable , reserved_3 , reserved_4 , reserved_5 , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength, in dB, at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. Note that the amplitude of the results are in dB. This is just to keep high dynamic range in the u16 sized data elements. Normally these are converted back to linear power or signal levels."] pub async fn os_mono_profile (& self) -> Result < OsMonoProfileStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: JsonWrapper (..) => "JSON_WRAPPER" , Messages :: OsPingParams (..) => "os_ping_params" , Messages :: OsMonoProfile (..) => "os_mono_profile" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , } } fn message_id (& self) -> u16 { match self { Messages :: JsonWrapper (..) => 10u16 , Messages :: OsPingParams (..) => 2197u16 , Messages :: OsMonoProfile (..) => 2198u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "JSON_WRAPPER" => Ok (10u16) , "os_ping_params" => Ok (2197u16) , "os_mono_profile" => Ok (2198u16) , "set_speed_of_sound" => Ok (1002u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: JsonWrapper (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsPingParams (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OsMonoProfile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 10u16 => Messages :: JsonWrapper (< JsonWrapperStruct as DeserializePayload > :: deserialize (payload)) , 2197u16 => Messages :: OsPingParams (< OsPingParamsStruct as DeserializePayload > :: deserialize (payload)) , 2198u16 => Messages :: OsMonoProfile (< OsMonoProfileStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:3383
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : <u8 as Into<_>>::into(payload [0usize]) , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:7431
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...(payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , vers...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : <u8 as Into<_>>::into(payload [0usize]) , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:7476
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ajor : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , rese...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : <u8 as Into<_>>::into(payload [1usize]) , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:7521
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...inor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } imp...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : <u8 as Into<_>>::into(payload [2usize]) , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:7561
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ion_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct ...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : <u8 as Into<_>>::into(payload [3usize]) , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:9886
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...e (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , fi...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : <u8 as Into<_>>::into(payload [0usize]) , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:9933
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...pe : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into ...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : <u8 as Into<_>>::into(payload [1usize]) , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:9987
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...yload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into ...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : <u8 as Into<_>>::into(payload [2usize]) , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:10041
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...yload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into ...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : <u8 as Into<_>>::into(payload [3usize]) , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:10095
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...yload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } imp...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : <u8 as Into<_>>::into(payload [4usize]) , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/common.rs:1:10135
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...ion_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruc...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : payload [5usize] . into () , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { SetDeviceId (SetDeviceIdStruct) , Ack (AckStruct) , AsciiText (AsciiTextStruct) , ProtocolVersion (ProtocolVersionStruct) , DeviceInformation (DeviceInformationStruct) , GeneralRequest (GeneralRequestStruct) , Nack (NackStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Ack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: AsciiText (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProtocolVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceInformation (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralRequest (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Nack (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 100u16 } fn name () -> & 'static str { "set_device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acknowledged."] pub struct AckStruct { # [doc = "The message ID that is ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is ACKnowledged."))] pub acked_id : u16 , } impl SerializePayload for AckStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . acked_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for AckStruct { fn deserialize (payload : & [u8]) -> Self { Self { acked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for AckStruct { fn id () -> u16 { 1u16 } fn name () -> & 'static str { "ack" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A message for transmitting text data."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A message for transmitting text data."] pub struct AsciiTextStruct { # [doc = "ASCII text message. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message. (not necessarily NULL terminated)"))] pub ascii_message : String , } impl SerializePayload for AsciiTextStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (self . ascii_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for AsciiTextStruct { fn deserialize (payload : & [u8]) -> Self { Self { ascii_message : String :: from_utf8 (payload [0usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for AsciiTextStruct { fn id () -> u16 { 3u16 } fn name () -> & 'static str { "ascii_text" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The protocol version"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The protocol version"] pub struct ProtocolVersionStruct { # [doc = "Protocol version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version major number."))] pub version_major : u8 , # [doc = "Protocol version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version minor number."))] pub version_minor : u8 , # [doc = "Protocol version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Protocol version patch number."))] pub version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for ProtocolVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProtocolVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { version_major : payload [0usize] . into () , version_minor : payload [1usize] . into () , version_patch : payload [2usize] . into () , reserved : payload [3usize] . into () , } } } impl MessageInfo for ProtocolVersionStruct { fn id () -> u16 { 5u16 } fn name () -> & 'static str { "protocol_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct DeviceInformationStruct { # [doc = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Ping Echosounder; 2: Ping360"))] pub device_type : u8 , # [doc = "device-specific hardware revision"] # [cfg_attr (feature = "schemars" , schemars (description = "device-specific hardware revision"))] pub device_revision : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u8 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u8 , # [doc = "Firmware version patch number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version patch number."))] pub firmware_version_patch : u8 , # [doc = "reserved"] # [cfg_attr (feature = "schemars" , schemars (description = "reserved"))] pub reserved : u8 , } impl SerializePayload for DeviceInformationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_revision . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_patch . to_le_bytes ()) ; buffer . extend_from_slice (& self . reserved . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceInformationStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_revision : payload [1usize] . into () , firmware_version_major : payload [2usize] . into () , firmware_version_minor : payload [3usize] . into () , firmware_version_patch : payload [4usize] . into () , reserved : <u8 as Into<_>>::into(payload [5usize]) , } } } impl MessageInfo for DeviceInformationStruct { fn id () -> u16 { 4u16 } fn name () -> & 'static str { "device_information" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Requests a specific message to be sent from the sonar to the host. Command timeout should be set to 50 msec."] pub struct GeneralRequestStruct { # [doc = "Message ID to be requested."] # [cfg_attr (feature = "schemars" , schemars (description = "Message ID to be requested."))] pub requested_id : u16 , } impl SerializePayload for GeneralRequestStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . requested_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralRequestStruct { fn deserialize (payload : & [u8]) -> Self { Self { requested_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GeneralRequestStruct { fn id () -> u16 { 6u16 } fn name () -> & 'static str { "general_request" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Not acknowledged."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Not acknowledged."] pub struct NackStruct { # [doc = "The message ID that is Not ACKnowledged."] # [cfg_attr (feature = "schemars" , schemars (description = "The message ID that is Not ACKnowledged."))] pub nacked_id : u16 , # [doc = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"] # [cfg_attr (feature = "schemars" , schemars (description = "ASCII text message indicating NACK condition. (not necessarily NULL terminated)"))] pub nack_message : String , } impl SerializePayload for NackStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . nacked_id . to_le_bytes ()) ; buffer . extend_from_slice (self . nack_message . as_bytes ()) ; buffer . push (0) ; buffer } } impl DeserializePayload for NackStruct { fn deserialize (payload : & [u8]) -> Self { Self { nacked_id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , nack_message : String :: from_utf8 (payload [2usize .. payload . len ()] . to_vec ()) . unwrap () , } } } impl MessageInfo for NackStruct { fn id () -> u16 { 2u16 } fn name () -> & 'static str { "nack" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (1-254). 0 is unknown and 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } # [doc = "The protocol version"] pub async fn protocol_version (& self) -> Result < ProtocolVersionStruct , PingError > { self . request () . await } # [doc = "Device information"] pub async fn device_information (& self) -> Result < DeviceInformationStruct , PingError > { self . request () . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: SetDeviceId (..) => "set_device_id" , Messages :: Ack (..) => "ack" , Messages :: AsciiText (..) => "ascii_text" , Messages :: ProtocolVersion (..) => "protocol_version" , Messages :: DeviceInformation (..) => "device_information" , Messages :: GeneralRequest (..) => "general_request" , Messages :: Nack (..) => "nack" , } } fn message_id (& self) -> u16 { match self { Messages :: SetDeviceId (..) => 100u16 , Messages :: Ack (..) => 1u16 , Messages :: AsciiText (..) => 3u16 , Messages :: ProtocolVersion (..) => 5u16 , Messages :: DeviceInformation (..) => 4u16 , Messages :: GeneralRequest (..) => 6u16 , Messages :: Nack (..) => 2u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "set_device_id" => Ok (100u16) , "ack" => Ok (1u16) , "ascii_text" => Ok (3u16) , "protocol_version" => Ok (5u16) , "device_information" => Ok (4u16) , "general_request" => Ok (6u16) , "nack" => Ok (2u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Ack (content) => (content as & dyn SerializePayload) . serialize () , Messages :: AsciiText (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProtocolVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceInformation (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralRequest (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Nack (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 100u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1u16 => Messages :: Ack (< AckStruct as DeserializePayload > :: deserialize (payload)) , 3u16 => Messages :: AsciiText (< AsciiTextStruct as DeserializePayload > :: deserialize (payload)) , 5u16 => Messages :: ProtocolVersion (< ProtocolVersionStruct as DeserializePayload > :: deserialize (payload)) , 4u16 => Messages :: DeviceInformation (< DeviceInformationStruct as DeserializePayload > :: deserialize (payload)) , 6u16 => Messages :: GeneralRequest (< GeneralRequestStruct as DeserializePayload > :: deserialize (payload)) , 2u16 => Messages :: Nack (< NackStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping1d.rs:1:7245
[INFO] [stdout]   |
[INFO] [stdout] 1 | ...e (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_model : payload [1usize] . into () , firmw...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { FirmwareVersion (FirmwareVersionStruct) , SetOssProfileConfiguration (SetOssProfileConfigurationStruct) , Range (RangeStruct) , PingInterval (PingIntervalStruct) , ContinuousStop (ContinuousStopStruct) , GainSetting (GainSettingStruct) , TransmitDuration (TransmitDurationStruct) , Voltage5 (Voltage5Struct) , DeviceId (DeviceIdStruct) , SetGainSetting (SetGainSettingStruct) , OssProfileConfiguration (OssProfileConfigurationStruct) , PcbTemperature (PcbTemperatureStruct) , SetModeAuto (SetModeAutoStruct) , ModeAuto (ModeAutoStruct) , GeneralInfo (GeneralInfoStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , SpeedOfSound (SpeedOfSoundStruct) , Distance (DistanceStruct) , SetRange (SetRangeStruct) , Profile (ProfileStruct) , SetPingEnable (SetPingEnableStruct) , SetPingInterval (SetPingIntervalStruct) , ContinuousStart (ContinuousStartStruct) , ProcessorTemperature (ProcessorTemperatureStruct) , PingEnable (PingEnableStruct) , GotoBootloader (GotoBootloaderStruct) , DistanceSimple (DistanceSimpleStruct) , SetDeviceId (SetDeviceIdStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: FirmwareVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetOssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Range (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStop (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TransmitDuration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Voltage5 (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetGainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PcbTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralInfo (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Distance (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetRange (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Profile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStart (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProcessorTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GotoBootloader (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DistanceSimple (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct FirmwareVersionStruct { # [doc = "Device type. 0: Unknown; 1: Echosounder"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Echosounder"))] pub device_type : u8 , # [doc = "Device model. 0: Unknown; 1: Ping1D"] # [cfg_attr (feature = "schemars" , schemars (description = "Device model. 0: Unknown; 1: Ping1D"))] pub device_model : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u16 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u16 , } impl SerializePayload for FirmwareVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_model . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer } } impl DeserializePayload for FirmwareVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_model : payload [1usize] . into () , firmware_version_major : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for FirmwareVersionStruct { fn id () -> u16 { 1200u16 } fn name () -> & 'static str { "firmware_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the profile output configuration. (Open source firmware only)"] pub struct SetOssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for SetOssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetOssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for SetOssProfileConfigurationStruct { fn id () -> u16 { 1007u16 } fn name () -> & 'static str { "set_oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub struct RangeStruct { # [doc = "The beginning of the scan range in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan range in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan range."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range."))] pub scan_length : u32 , } impl SerializePayload for RangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for RangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for RangeStruct { fn id () -> u16 { 1204u16 } fn name () -> & 'static str { "range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct PingIntervalStruct { # [doc = "The minimum interval between acoustic measurements. The actual interval may be longer."] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum interval between acoustic measurements. The actual interval may be longer."))] pub ping_interval : u16 , } impl SerializePayload for PingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PingIntervalStruct { fn id () -> u16 { 1206u16 } fn name () -> & 'static str { "ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to stop the continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to stop the continuous data stream of profile messages."] pub struct ContinuousStopStruct { # [doc = "The message id to stop streaming. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stop streaming. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStopStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStopStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStopStruct { fn id () -> u16 { 1401u16 } fn name () -> & 'static str { "continuous_stop" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current gain setting."] pub struct GainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for GainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for GainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GainSettingStruct { fn id () -> u16 { 1207u16 } fn name () -> & 'static str { "gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The duration of the acoustic activation/transmission."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The duration of the acoustic activation/transmission."] pub struct TransmitDurationStruct { # [doc = "Acoustic pulse duration."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic pulse duration."))] pub transmit_duration : u16 , } impl SerializePayload for TransmitDurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransmitDurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { transmit_duration : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TransmitDurationStruct { fn id () -> u16 { 1208u16 } fn name () -> & 'static str { "transmit_duration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The 5V rail voltage."] pub struct Voltage5Struct { # [doc = "The 5V rail voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] pub voltage_5 : u16 , } impl SerializePayload for Voltage5Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for Voltage5Struct { fn deserialize (payload : & [u8]) -> Self { Self { voltage_5 : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for Voltage5Struct { fn id () -> u16 { 1202u16 } fn name () -> & 'static str { "voltage_5" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The device ID."] pub struct DeviceIdStruct { # [doc = "The device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for DeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for DeviceIdStruct { fn id () -> u16 { 1201u16 } fn name () -> & 'static str { "device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the current gain setting."] pub struct SetGainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , } impl SerializePayload for SetGainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetGainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : payload [0usize] . into () , } } } impl MessageInfo for SetGainSettingStruct { fn id () -> u16 { 1005u16 } fn name () -> & 'static str { "set_gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the profile output configuration. (Open source firmware only)"] pub struct OssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for OssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for OssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for OssProfileConfigurationStruct { fn id () -> u16 { 1301u16 } fn name () -> & 'static str { "oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the on-board thermistor."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the on-board thermistor."] pub struct PcbTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub pcb_temperature : u16 , } impl SerializePayload for PcbTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . pcb_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for PcbTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { pcb_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PcbTemperatureStruct { fn id () -> u16 { 1214u16 } fn name () -> & 'static str { "pcb_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] pub struct SetModeAutoStruct { # [doc = "0: manual mode. 1: auto mode."] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode. 1: auto mode."))] pub mode_auto : u8 , } impl SerializePayload for SetModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for SetModeAutoStruct { fn id () -> u16 { 1003u16 } fn name () -> & 'static str { "set_mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub struct ModeAutoStruct { # [doc = "0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for ModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for ModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for ModeAutoStruct { fn id () -> u16 { 1205u16 } fn name () -> & 'static str { "mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "General information."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "General information."] pub struct GeneralInfoStruct { # [doc = "Firmware major version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware major version."))] pub firmware_version_major : u16 , # [doc = "Firmware minor version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware minor version."))] pub firmware_version_minor : u16 , # [doc = "Device supply voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "Device supply voltage."))] pub voltage_5 : u16 , # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , # [doc = "The current operating mode of the device. 0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. 0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for GeneralInfoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralInfoStruct { fn deserialize (payload : & [u8]) -> Self { Self { firmware_version_major : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , voltage_5 : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_interval : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , gain_setting : payload [8usize] . into () , mode_auto : payload [9usize] . into () , } } } impl MessageInfo for GeneralInfoStruct { fn id () -> u16 { 1210u16 } fn name () -> & 'static str { "general_info" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound used for distance calculations."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The speed of sound used for distance calculations."] pub struct SpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SpeedOfSoundStruct { fn id () -> u16 { 1203u16 } fn name () -> & 'static str { "speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub struct DistanceStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for DistanceStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for DistanceStruct { fn id () -> u16 { 1212u16 } fn name () -> & 'static str { "distance" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the scan range for acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the scan range for acoustic measurements."] pub struct SetRangeStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub scan_start : u32 , # [doc = "The length of the scan range. Minimum 1000."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range. Minimum 1000."))] pub scan_length : u32 , } impl SerializePayload for SetRangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetRangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetRangeStruct { fn id () -> u16 { 1001u16 } fn name () -> & 'static str { "set_range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub struct ProfileStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data : Vec < u8 > , } impl SerializePayload for ProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . profile_data_length . to_le_bytes ()) ; for value in self . profile_data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for ProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , profile_data_length : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , profile_data : payload [24usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for ProfileStruct { fn id () -> u16 { 1300u16 } fn name () -> & 'static str { "profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Enable or disable acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Enable or disable acoustic measurements."] pub struct SetPingEnableStruct { # [doc = "0: Disable, 1: Enable."] # [cfg_attr (feature = "schemars" , schemars (description = "0: Disable, 1: Enable."))] pub ping_enabled : u8 , } impl SerializePayload for SetPingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for SetPingEnableStruct { fn id () -> u16 { 1006u16 } fn name () -> & 'static str { "set_ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct SetPingIntervalStruct { # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , } impl SerializePayload for SetPingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetPingIntervalStruct { fn id () -> u16 { 1004u16 } fn name () -> & 'static str { "set_ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to initiate continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to initiate continuous data stream of profile messages."] pub struct ContinuousStartStruct { # [doc = "The message id to stream. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stream. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStartStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStartStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStartStruct { fn id () -> u16 { 1400u16 } fn name () -> & 'static str { "continuous_start" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the device cpu."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the device cpu."] pub struct ProcessorTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub processor_temperature : u16 , } impl SerializePayload for ProcessorTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . processor_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProcessorTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { processor_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ProcessorTemperatureStruct { fn id () -> u16 { 1213u16 } fn name () -> & 'static str { "processor_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic output enabled state."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acoustic output enabled state."] pub struct PingEnableStruct { # [doc = "The state of the acoustic output. 0: disabled, 1:enabled"] # [cfg_attr (feature = "schemars" , schemars (description = "The state of the acoustic output. 0: disabled, 1:enabled"))] pub ping_enabled : u8 , } impl SerializePayload for PingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for PingEnableStruct { fn id () -> u16 { 1215u16 } fn name () -> & 'static str { "ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Send the device into the bootloader. This is useful for firmware updates."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Send the device into the bootloader. This is useful for firmware updates."] pub struct GotoBootloaderStruct { } impl SerializePayload for GotoBootloaderStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for GotoBootloaderStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for GotoBootloaderStruct { fn id () -> u16 { 1100u16 } fn name () -> & 'static str { "goto_bootloader" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate."] pub struct DistanceSimpleStruct { # [doc = "Distance to the target."] # [cfg_attr (feature = "schemars" , schemars (description = "Distance to the target."))] pub distance : u32 , # [doc = "Confidence in the distance measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the distance measurement."))] pub confidence : u8 , } impl SerializePayload for DistanceSimpleStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceSimpleStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : payload [4usize] . into () , } } } impl MessageInfo for DistanceSimpleStruct { fn id () -> u16 { 1211u16 } fn name () -> & 'static str { "distance_simple" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 1000u16 } fn name () -> & 'static str { "set_device_id" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Device information"] pub async fn firmware_version (& self) -> Result < FirmwareVersionStruct , PingError > { self . request () . await } # [doc = "Set the profile output configuration. (Open source firmware only)"] # [doc = "# Arguments"] # [doc = "* `number_of_points` - Not documented"] # [doc = "* `normalization_enabled` - If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [doc = "* `enhance_enabled` - If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] pub async fn set_oss_profile_configuration (& self , number_of_points : u16 , normalization_enabled : u8 , enhance_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetOssProfileConfiguration (SetOssProfileConfigurationStruct { number_of_points , normalization_enabled , enhance_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetOssProfileConfigurationStruct :: id ()) . await } # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub async fn range (& self) -> Result < RangeStruct , PingError > { self . request () . await } # [doc = "The interval between acoustic measurements."] pub async fn ping_interval (& self) -> Result < PingIntervalStruct , PingError > { self . request () . await } # [doc = "Command to stop the continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stop streaming. 1300: profile"] pub async fn continuous_stop (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStop (ContinuousStopStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The current gain setting."] pub async fn gain_setting (& self) -> Result < GainSettingStruct , PingError > { self . request () . await } # [doc = "The duration of the acoustic activation/transmission."] pub async fn transmit_duration (& self) -> Result < TransmitDurationStruct , PingError > { self . request () . await } # [doc = "The 5V rail voltage."] pub async fn voltage_5 (& self) -> Result < Voltage5Struct , PingError > { self . request () . await } # [doc = "The device ID."] pub async fn device_id (& self) -> Result < DeviceIdStruct , PingError > { self . request () . await } # [doc = "Set the current gain setting."] # [doc = "# Arguments"] # [doc = "* `gain_setting` - The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] pub async fn set_gain_setting (& self , gain_setting : u8) -> Result < () , PingError > { let request = Messages :: SetGainSetting (SetGainSettingStruct { gain_setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetGainSettingStruct :: id ()) . await } # [doc = "Get the profile output configuration. (Open source firmware only)"] pub async fn oss_profile_configuration (& self) -> Result < OssProfileConfigurationStruct , PingError > { self . request () . await } # [doc = "Temperature of the on-board thermistor."] pub async fn pcb_temperature (& self) -> Result < PcbTemperatureStruct , PingError > { self . request () . await } # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] # [doc = "# Arguments"] # [doc = "* `mode_auto` - 0: manual mode. 1: auto mode."] pub async fn set_mode_auto (& self , mode_auto : u8) -> Result < () , PingError > { let request = Messages :: SetModeAuto (SetModeAutoStruct { mode_auto , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetModeAutoStruct :: id ()) . await } # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub async fn mode_auto (& self) -> Result < ModeAutoStruct , PingError > { self . request () . await } # [doc = "General information."] pub async fn general_info (& self) -> Result < GeneralInfoStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound used for distance calculations."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetSpeedOfSoundStruct :: id ()) . await } # [doc = "The speed of sound used for distance calculations."] pub async fn speed_of_sound (& self) -> Result < SpeedOfSoundStruct , PingError > { self . request () . await } # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub async fn distance (& self) -> Result < DistanceStruct , PingError > { self . request () . await } # [doc = "Set the scan range for acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `scan_start` \\[mm\\] - Not documented"] # [doc = "* `scan_length` \\[mm\\] - The length of the scan range. Minimum 1000."] pub async fn set_range (& self , scan_start : u32 , scan_length : u32) -> Result < () , PingError > { let request = Messages :: SetRange (SetRangeStruct { scan_start , scan_length , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetRangeStruct :: id ()) . await } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub async fn profile (& self) -> Result < ProfileStruct , PingError > { self . request () . await } # [doc = "Enable or disable acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_enabled` - 0: Disable, 1: Enable."] pub async fn set_ping_enable (& self , ping_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetPingEnable (SetPingEnableStruct { ping_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingEnableStruct :: id ()) . await } # [doc = "The interval between acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_interval` \\[ms\\] - The interval between acoustic measurements."] pub async fn set_ping_interval (& self , ping_interval : u16) -> Result < () , PingError > { let request = Messages :: SetPingInterval (SetPingIntervalStruct { ping_interval , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingIntervalStruct :: id ()) . await } # [doc = "Command to initiate continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stream. 1300: profile"] pub async fn continuous_start (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStart (ContinuousStartStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Temperature of the device cpu."] pub async fn processor_temperature (& self) -> Result < ProcessorTemperatureStruct , PingError > { self . request () . await } # [doc = "Acoustic output enabled state."] pub async fn ping_enable (& self) -> Result < PingEnableStruct , PingError > { self . request () . await } # [doc = "Send the device into the bootloader. This is useful for firmware updates."] # [doc = "# Arguments"] pub async fn goto_bootloader (& self ,) -> Result < () , PingError > { let request = Messages :: GotoBootloader (GotoBootloaderStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The distance to target with confidence estimate."] pub async fn distance_simple (& self) -> Result < DistanceSimpleStruct , PingError > { self . request () . await } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (0-254). 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: FirmwareVersion (..) => "firmware_version" , Messages :: SetOssProfileConfiguration (..) => "set_oss_profile_configuration" , Messages :: Range (..) => "range" , Messages :: PingInterval (..) => "ping_interval" , Messages :: ContinuousStop (..) => "continuous_stop" , Messages :: GainSetting (..) => "gain_setting" , Messages :: TransmitDuration (..) => "transmit_duration" , Messages :: Voltage5 (..) => "voltage_5" , Messages :: DeviceId (..) => "device_id" , Messages :: SetGainSetting (..) => "set_gain_setting" , Messages :: OssProfileConfiguration (..) => "oss_profile_configuration" , Messages :: PcbTemperature (..) => "pcb_temperature" , Messages :: SetModeAuto (..) => "set_mode_auto" , Messages :: ModeAuto (..) => "mode_auto" , Messages :: GeneralInfo (..) => "general_info" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , Messages :: SpeedOfSound (..) => "speed_of_sound" , Messages :: Distance (..) => "distance" , Messages :: SetRange (..) => "set_range" , Messages :: Profile (..) => "profile" , Messages :: SetPingEnable (..) => "set_ping_enable" , Messages :: SetPingInterval (..) => "set_ping_interval" , Messages :: ContinuousStart (..) => "continuous_start" , Messages :: ProcessorTemperature (..) => "processor_temperature" , Messages :: PingEnable (..) => "ping_enable" , Messages :: GotoBootloader (..) => "goto_bootloader" , Messages :: DistanceSimple (..) => "distance_simple" , Messages :: SetDeviceId (..) => "set_device_id" , } } fn message_id (& self) -> u16 { match self { Messages :: FirmwareVersion (..) => 1200u16 , Messages :: SetOssProfileConfiguration (..) => 1007u16 , Messages :: Range (..) => 1204u16 , Messages :: PingInterval (..) => 1206u16 , Messages :: ContinuousStop (..) => 1401u16 , Messages :: GainSetting (..) => 1207u16 , Messages :: TransmitDuration (..) => 1208u16 , Messages :: Voltage5 (..) => 1202u16 , Messages :: DeviceId (..) => 1201u16 , Messages :: SetGainSetting (..) => 1005u16 , Messages :: OssProfileConfiguration (..) => 1301u16 , Messages :: PcbTemperature (..) => 1214u16 , Messages :: SetModeAuto (..) => 1003u16 , Messages :: ModeAuto (..) => 1205u16 , Messages :: GeneralInfo (..) => 1210u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , Messages :: SpeedOfSound (..) => 1203u16 , Messages :: Distance (..) => 1212u16 , Messages :: SetRange (..) => 1001u16 , Messages :: Profile (..) => 1300u16 , Messages :: SetPingEnable (..) => 1006u16 , Messages :: SetPingInterval (..) => 1004u16 , Messages :: ContinuousStart (..) => 1400u16 , Messages :: ProcessorTemperature (..) => 1213u16 , Messages :: PingEnable (..) => 1215u16 , Messages :: GotoBootloader (..) => 1100u16 , Messages :: DistanceSimple (..) => 1211u16 , Messages :: SetDeviceId (..) => 1000u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "firmware_version" => Ok (1200u16) , "set_oss_profile_configuration" => Ok (1007u16) , "range" => Ok (1204u16) , "ping_interval" => Ok (1206u16) , "continuous_stop" => Ok (1401u16) , "gain_setting" => Ok (1207u16) , "transmit_duration" => Ok (1208u16) , "voltage_5" => Ok (1202u16) , "device_id" => Ok (1201u16) , "set_gain_setting" => Ok (1005u16) , "oss_profile_configuration" => Ok (1301u16) , "pcb_temperature" => Ok (1214u16) , "set_mode_auto" => Ok (1003u16) , "mode_auto" => Ok (1205u16) , "general_info" => Ok (1210u16) , "set_speed_of_sound" => Ok (1002u16) , "speed_of_sound" => Ok (1203u16) , "distance" => Ok (1212u16) , "set_range" => Ok (1001u16) , "profile" => Ok (1300u16) , "set_ping_enable" => Ok (1006u16) , "set_ping_interval" => Ok (1004u16) , "continuous_start" => Ok (1400u16) , "processor_temperature" => Ok (1213u16) , "ping_enable" => Ok (1215u16) , "goto_bootloader" => Ok (1100u16) , "distance_simple" => Ok (1211u16) , "set_device_id" => Ok (1000u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: FirmwareVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetOssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Range (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStop (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TransmitDuration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Voltage5 (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetGainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PcbTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralInfo (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Distance (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetRange (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Profile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStart (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProcessorTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GotoBootloader (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DistanceSimple (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 1200u16 => Messages :: FirmwareVersion (< FirmwareVersionStruct as DeserializePayload > :: deserialize (payload)) , 1007u16 => Messages :: SetOssProfileConfiguration (< SetOssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1204u16 => Messages :: Range (< RangeStruct as DeserializePayload > :: deserialize (payload)) , 1206u16 => Messages :: PingInterval (< PingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1401u16 => Messages :: ContinuousStop (< ContinuousStopStruct as DeserializePayload > :: deserialize (payload)) , 1207u16 => Messages :: GainSetting (< GainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1208u16 => Messages :: TransmitDuration (< TransmitDurationStruct as DeserializePayload > :: deserialize (payload)) , 1202u16 => Messages :: Voltage5 (< Voltage5Struct as DeserializePayload > :: deserialize (payload)) , 1201u16 => Messages :: DeviceId (< DeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1005u16 => Messages :: SetGainSetting (< SetGainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1301u16 => Messages :: OssProfileConfiguration (< OssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1214u16 => Messages :: PcbTemperature (< PcbTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1003u16 => Messages :: SetModeAuto (< SetModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1205u16 => Messages :: ModeAuto (< ModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1210u16 => Messages :: GeneralInfo (< GeneralInfoStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1203u16 => Messages :: SpeedOfSound (< SpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1212u16 => Messages :: Distance (< DistanceStruct as DeserializePayload > :: deserialize (payload)) , 1001u16 => Messages :: SetRange (< SetRangeStruct as DeserializePayload > :: deserialize (payload)) , 1300u16 => Messages :: Profile (< ProfileStruct as DeserializePayload > :: deserialize (payload)) , 1006u16 => Messages :: SetPingEnable (< SetPingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1004u16 => Messages :: SetPingInterval (< SetPingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1400u16 => Messages :: ContinuousStart (< ContinuousStartStruct as DeserializePayload > :: deserialize (payload)) , 1213u16 => Messages :: ProcessorTemperature (< ProcessorTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1215u16 => Messages :: PingEnable (< PingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1100u16 => Messages :: GotoBootloader (< GotoBootloaderStruct as DeserializePayload > :: deserialize (payload)) , 1211u16 => Messages :: DistanceSimple (< DistanceSimpleStruct as DeserializePayload > :: deserialize (payload)) , 1000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { FirmwareVersion (FirmwareVersionStruct) , SetOssProfileConfiguration (SetOssProfileConfigurationStruct) , Range (RangeStruct) , PingInterval (PingIntervalStruct) , ContinuousStop (ContinuousStopStruct) , GainSetting (GainSettingStruct) , TransmitDuration (TransmitDurationStruct) , Voltage5 (Voltage5Struct) , DeviceId (DeviceIdStruct) , SetGainSetting (SetGainSettingStruct) , OssProfileConfiguration (OssProfileConfigurationStruct) , PcbTemperature (PcbTemperatureStruct) , SetModeAuto (SetModeAutoStruct) , ModeAuto (ModeAutoStruct) , GeneralInfo (GeneralInfoStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , SpeedOfSound (SpeedOfSoundStruct) , Distance (DistanceStruct) , SetRange (SetRangeStruct) , Profile (ProfileStruct) , SetPingEnable (SetPingEnableStruct) , SetPingInterval (SetPingIntervalStruct) , ContinuousStart (ContinuousStartStruct) , ProcessorTemperature (ProcessorTemperatureStruct) , PingEnable (PingEnableStruct) , GotoBootloader (GotoBootloaderStruct) , DistanceSimple (DistanceSimpleStruct) , SetDeviceId (SetDeviceIdStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: FirmwareVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetOssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Range (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStop (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TransmitDuration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Voltage5 (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetGainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PcbTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralInfo (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Distance (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetRange (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Profile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStart (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProcessorTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GotoBootloader (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DistanceSimple (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct FirmwareVersionStruct { # [doc = "Device type. 0: Unknown; 1: Echosounder"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Echosounder"))] pub device_type : u8 , # [doc = "Device model. 0: Unknown; 1: Ping1D"] # [cfg_attr (feature = "schemars" , schemars (description = "Device model. 0: Unknown; 1: Ping1D"))] pub device_model : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u16 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u16 , } impl SerializePayload for FirmwareVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_model . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer } } impl DeserializePayload for FirmwareVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] , device_model : payload [1usize] . into () , firmware_version_major : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for FirmwareVersionStruct { fn id () -> u16 { 1200u16 } fn name () -> & 'static str { "firmware_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the profile output configuration. (Open source firmware only)"] pub struct SetOssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for SetOssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetOssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for SetOssProfileConfigurationStruct { fn id () -> u16 { 1007u16 } fn name () -> & 'static str { "set_oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub struct RangeStruct { # [doc = "The beginning of the scan range in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan range in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan range."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range."))] pub scan_length : u32 , } impl SerializePayload for RangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for RangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for RangeStruct { fn id () -> u16 { 1204u16 } fn name () -> & 'static str { "range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct PingIntervalStruct { # [doc = "The minimum interval between acoustic measurements. The actual interval may be longer."] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum interval between acoustic measurements. The actual interval may be longer."))] pub ping_interval : u16 , } impl SerializePayload for PingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PingIntervalStruct { fn id () -> u16 { 1206u16 } fn name () -> & 'static str { "ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to stop the continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to stop the continuous data stream of profile messages."] pub struct ContinuousStopStruct { # [doc = "The message id to stop streaming. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stop streaming. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStopStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStopStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStopStruct { fn id () -> u16 { 1401u16 } fn name () -> & 'static str { "continuous_stop" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current gain setting."] pub struct GainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for GainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for GainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GainSettingStruct { fn id () -> u16 { 1207u16 } fn name () -> & 'static str { "gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The duration of the acoustic activation/transmission."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The duration of the acoustic activation/transmission."] pub struct TransmitDurationStruct { # [doc = "Acoustic pulse duration."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic pulse duration."))] pub transmit_duration : u16 , } impl SerializePayload for TransmitDurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransmitDurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { transmit_duration : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TransmitDurationStruct { fn id () -> u16 { 1208u16 } fn name () -> & 'static str { "transmit_duration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The 5V rail voltage."] pub struct Voltage5Struct { # [doc = "The 5V rail voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] pub voltage_5 : u16 , } impl SerializePayload for Voltage5Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for Voltage5Struct { fn deserialize (payload : & [u8]) -> Self { Self { voltage_5 : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for Voltage5Struct { fn id () -> u16 { 1202u16 } fn name () -> & 'static str { "voltage_5" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The device ID."] pub struct DeviceIdStruct { # [doc = "The device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for DeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for DeviceIdStruct { fn id () -> u16 { 1201u16 } fn name () -> & 'static str { "device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the current gain setting."] pub struct SetGainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , } impl SerializePayload for SetGainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetGainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : payload [0usize] . into () , } } } impl MessageInfo for SetGainSettingStruct { fn id () -> u16 { 1005u16 } fn name () -> & 'static str { "set_gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the profile output configuration. (Open source firmware only)"] pub struct OssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for OssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for OssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for OssProfileConfigurationStruct { fn id () -> u16 { 1301u16 } fn name () -> & 'static str { "oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the on-board thermistor."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the on-board thermistor."] pub struct PcbTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub pcb_temperature : u16 , } impl SerializePayload for PcbTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . pcb_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for PcbTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { pcb_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PcbTemperatureStruct { fn id () -> u16 { 1214u16 } fn name () -> & 'static str { "pcb_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] pub struct SetModeAutoStruct { # [doc = "0: manual mode. 1: auto mode."] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode. 1: auto mode."))] pub mode_auto : u8 , } impl SerializePayload for SetModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for SetModeAutoStruct { fn id () -> u16 { 1003u16 } fn name () -> & 'static str { "set_mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub struct ModeAutoStruct { # [doc = "0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for ModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for ModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for ModeAutoStruct { fn id () -> u16 { 1205u16 } fn name () -> & 'static str { "mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "General information."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "General information."] pub struct GeneralInfoStruct { # [doc = "Firmware major version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware major version."))] pub firmware_version_major : u16 , # [doc = "Firmware minor version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware minor version."))] pub firmware_version_minor : u16 , # [doc = "Device supply voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "Device supply voltage."))] pub voltage_5 : u16 , # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , # [doc = "The current operating mode of the device. 0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. 0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for GeneralInfoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralInfoStruct { fn deserialize (payload : & [u8]) -> Self { Self { firmware_version_major : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , voltage_5 : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_interval : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , gain_setting : payload [8usize] . into () , mode_auto : payload [9usize] . into () , } } } impl MessageInfo for GeneralInfoStruct { fn id () -> u16 { 1210u16 } fn name () -> & 'static str { "general_info" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound used for distance calculations."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The speed of sound used for distance calculations."] pub struct SpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SpeedOfSoundStruct { fn id () -> u16 { 1203u16 } fn name () -> & 'static str { "speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub struct DistanceStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for DistanceStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for DistanceStruct { fn id () -> u16 { 1212u16 } fn name () -> & 'static str { "distance" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the scan range for acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the scan range for acoustic measurements."] pub struct SetRangeStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub scan_start : u32 , # [doc = "The length of the scan range. Minimum 1000."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range. Minimum 1000."))] pub scan_length : u32 , } impl SerializePayload for SetRangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetRangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetRangeStruct { fn id () -> u16 { 1001u16 } fn name () -> & 'static str { "set_range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub struct ProfileStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data : Vec < u8 > , } impl SerializePayload for ProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . profile_data_length . to_le_bytes ()) ; for value in self . profile_data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for ProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , profile_data_length : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , profile_data : payload [24usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for ProfileStruct { fn id () -> u16 { 1300u16 } fn name () -> & 'static str { "profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Enable or disable acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Enable or disable acoustic measurements."] pub struct SetPingEnableStruct { # [doc = "0: Disable, 1: Enable."] # [cfg_attr (feature = "schemars" , schemars (description = "0: Disable, 1: Enable."))] pub ping_enabled : u8 , } impl SerializePayload for SetPingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for SetPingEnableStruct { fn id () -> u16 { 1006u16 } fn name () -> & 'static str { "set_ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct SetPingIntervalStruct { # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , } impl SerializePayload for SetPingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetPingIntervalStruct { fn id () -> u16 { 1004u16 } fn name () -> & 'static str { "set_ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to initiate continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to initiate continuous data stream of profile messages."] pub struct ContinuousStartStruct { # [doc = "The message id to stream. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stream. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStartStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStartStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStartStruct { fn id () -> u16 { 1400u16 } fn name () -> & 'static str { "continuous_start" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the device cpu."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the device cpu."] pub struct ProcessorTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub processor_temperature : u16 , } impl SerializePayload for ProcessorTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . processor_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProcessorTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { processor_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ProcessorTemperatureStruct { fn id () -> u16 { 1213u16 } fn name () -> & 'static str { "processor_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic output enabled state."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acoustic output enabled state."] pub struct PingEnableStruct { # [doc = "The state of the acoustic output. 0: disabled, 1:enabled"] # [cfg_attr (feature = "schemars" , schemars (description = "The state of the acoustic output. 0: disabled, 1:enabled"))] pub ping_enabled : u8 , } impl SerializePayload for PingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for PingEnableStruct { fn id () -> u16 { 1215u16 } fn name () -> & 'static str { "ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Send the device into the bootloader. This is useful for firmware updates."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Send the device into the bootloader. This is useful for firmware updates."] pub struct GotoBootloaderStruct { } impl SerializePayload for GotoBootloaderStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for GotoBootloaderStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for GotoBootloaderStruct { fn id () -> u16 { 1100u16 } fn name () -> & 'static str { "goto_bootloader" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate."] pub struct DistanceSimpleStruct { # [doc = "Distance to the target."] # [cfg_attr (feature = "schemars" , schemars (description = "Distance to the target."))] pub distance : u32 , # [doc = "Confidence in the distance measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the distance measurement."))] pub confidence : u8 , } impl SerializePayload for DistanceSimpleStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceSimpleStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : payload [4usize] . into () , } } } impl MessageInfo for DistanceSimpleStruct { fn id () -> u16 { 1211u16 } fn name () -> & 'static str { "distance_simple" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 1000u16 } fn name () -> & 'static str { "set_device_id" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Device information"] pub async fn firmware_version (& self) -> Result < FirmwareVersionStruct , PingError > { self . request () . await } # [doc = "Set the profile output configuration. (Open source firmware only)"] # [doc = "# Arguments"] # [doc = "* `number_of_points` - Not documented"] # [doc = "* `normalization_enabled` - If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [doc = "* `enhance_enabled` - If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] pub async fn set_oss_profile_configuration (& self , number_of_points : u16 , normalization_enabled : u8 , enhance_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetOssProfileConfiguration (SetOssProfileConfigurationStruct { number_of_points , normalization_enabled , enhance_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetOssProfileConfigurationStruct :: id ()) . await } # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub async fn range (& self) -> Result < RangeStruct , PingError > { self . request () . await } # [doc = "The interval between acoustic measurements."] pub async fn ping_interval (& self) -> Result < PingIntervalStruct , PingError > { self . request () . await } # [doc = "Command to stop the continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stop streaming. 1300: profile"] pub async fn continuous_stop (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStop (ContinuousStopStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The current gain setting."] pub async fn gain_setting (& self) -> Result < GainSettingStruct , PingError > { self . request () . await } # [doc = "The duration of the acoustic activation/transmission."] pub async fn transmit_duration (& self) -> Result < TransmitDurationStruct , PingError > { self . request () . await } # [doc = "The 5V rail voltage."] pub async fn voltage_5 (& self) -> Result < Voltage5Struct , PingError > { self . request () . await } # [doc = "The device ID."] pub async fn device_id (& self) -> Result < DeviceIdStruct , PingError > { self . request () . await } # [doc = "Set the current gain setting."] # [doc = "# Arguments"] # [doc = "* `gain_setting` - The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] pub async fn set_gain_setting (& self , gain_setting : u8) -> Result < () , PingError > { let request = Messages :: SetGainSetting (SetGainSettingStruct { gain_setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetGainSettingStruct :: id ()) . await } # [doc = "Get the profile output configuration. (Open source firmware only)"] pub async fn oss_profile_configuration (& self) -> Result < OssProfileConfigurationStruct , PingError > { self . request () . await } # [doc = "Temperature of the on-board thermistor."] pub async fn pcb_temperature (& self) -> Result < PcbTemperatureStruct , PingError > { self . request () . await } # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] # [doc = "# Arguments"] # [doc = "* `mode_auto` - 0: manual mode. 1: auto mode."] pub async fn set_mode_auto (& self , mode_auto : u8) -> Result < () , PingError > { let request = Messages :: SetModeAuto (SetModeAutoStruct { mode_auto , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetModeAutoStruct :: id ()) . await } # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub async fn mode_auto (& self) -> Result < ModeAutoStruct , PingError > { self . request () . await } # [doc = "General information."] pub async fn general_info (& self) -> Result < GeneralInfoStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound used for distance calculations."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetSpeedOfSoundStruct :: id ()) . await } # [doc = "The speed of sound used for distance calculations."] pub async fn speed_of_sound (& self) -> Result < SpeedOfSoundStruct , PingError > { self . request () . await } # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub async fn distance (& self) -> Result < DistanceStruct , PingError > { self . request () . await } # [doc = "Set the scan range for acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `scan_start` \\[mm\\] - Not documented"] # [doc = "* `scan_length` \\[mm\\] - The length of the scan range. Minimum 1000."] pub async fn set_range (& self , scan_start : u32 , scan_length : u32) -> Result < () , PingError > { let request = Messages :: SetRange (SetRangeStruct { scan_start , scan_length , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetRangeStruct :: id ()) . await } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub async fn profile (& self) -> Result < ProfileStruct , PingError > { self . request () . await } # [doc = "Enable or disable acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_enabled` - 0: Disable, 1: Enable."] pub async fn set_ping_enable (& self , ping_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetPingEnable (SetPingEnableStruct { ping_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingEnableStruct :: id ()) . await } # [doc = "The interval between acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_interval` \\[ms\\] - The interval between acoustic measurements."] pub async fn set_ping_interval (& self , ping_interval : u16) -> Result < () , PingError > { let request = Messages :: SetPingInterval (SetPingIntervalStruct { ping_interval , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingIntervalStruct :: id ()) . await } # [doc = "Command to initiate continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stream. 1300: profile"] pub async fn continuous_start (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStart (ContinuousStartStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Temperature of the device cpu."] pub async fn processor_temperature (& self) -> Result < ProcessorTemperatureStruct , PingError > { self . request () . await } # [doc = "Acoustic output enabled state."] pub async fn ping_enable (& self) -> Result < PingEnableStruct , PingError > { self . request () . await } # [doc = "Send the device into the bootloader. This is useful for firmware updates."] # [doc = "# Arguments"] pub async fn goto_bootloader (& self ,) -> Result < () , PingError > { let request = Messages :: GotoBootloader (GotoBootloaderStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The distance to target with confidence estimate."] pub async fn distance_simple (& self) -> Result < DistanceSimpleStruct , PingError > { self . request () . await } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (0-254). 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: FirmwareVersion (..) => "firmware_version" , Messages :: SetOssProfileConfiguration (..) => "set_oss_profile_configuration" , Messages :: Range (..) => "range" , Messages :: PingInterval (..) => "ping_interval" , Messages :: ContinuousStop (..) => "continuous_stop" , Messages :: GainSetting (..) => "gain_setting" , Messages :: TransmitDuration (..) => "transmit_duration" , Messages :: Voltage5 (..) => "voltage_5" , Messages :: DeviceId (..) => "device_id" , Messages :: SetGainSetting (..) => "set_gain_setting" , Messages :: OssProfileConfiguration (..) => "oss_profile_configuration" , Messages :: PcbTemperature (..) => "pcb_temperature" , Messages :: SetModeAuto (..) => "set_mode_auto" , Messages :: ModeAuto (..) => "mode_auto" , Messages :: GeneralInfo (..) => "general_info" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , Messages :: SpeedOfSound (..) => "speed_of_sound" , Messages :: Distance (..) => "distance" , Messages :: SetRange (..) => "set_range" , Messages :: Profile (..) => "profile" , Messages :: SetPingEnable (..) => "set_ping_enable" , Messages :: SetPingInterval (..) => "set_ping_interval" , Messages :: ContinuousStart (..) => "continuous_start" , Messages :: ProcessorTemperature (..) => "processor_temperature" , Messages :: PingEnable (..) => "ping_enable" , Messages :: GotoBootloader (..) => "goto_bootloader" , Messages :: DistanceSimple (..) => "distance_simple" , Messages :: SetDeviceId (..) => "set_device_id" , } } fn message_id (& self) -> u16 { match self { Messages :: FirmwareVersion (..) => 1200u16 , Messages :: SetOssProfileConfiguration (..) => 1007u16 , Messages :: Range (..) => 1204u16 , Messages :: PingInterval (..) => 1206u16 , Messages :: ContinuousStop (..) => 1401u16 , Messages :: GainSetting (..) => 1207u16 , Messages :: TransmitDuration (..) => 1208u16 , Messages :: Voltage5 (..) => 1202u16 , Messages :: DeviceId (..) => 1201u16 , Messages :: SetGainSetting (..) => 1005u16 , Messages :: OssProfileConfiguration (..) => 1301u16 , Messages :: PcbTemperature (..) => 1214u16 , Messages :: SetModeAuto (..) => 1003u16 , Messages :: ModeAuto (..) => 1205u16 , Messages :: GeneralInfo (..) => 1210u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , Messages :: SpeedOfSound (..) => 1203u16 , Messages :: Distance (..) => 1212u16 , Messages :: SetRange (..) => 1001u16 , Messages :: Profile (..) => 1300u16 , Messages :: SetPingEnable (..) => 1006u16 , Messages :: SetPingInterval (..) => 1004u16 , Messages :: ContinuousStart (..) => 1400u16 , Messages :: ProcessorTemperature (..) => 1213u16 , Messages :: PingEnable (..) => 1215u16 , Messages :: GotoBootloader (..) => 1100u16 , Messages :: DistanceSimple (..) => 1211u16 , Messages :: SetDeviceId (..) => 1000u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "firmware_version" => Ok (1200u16) , "set_oss_profile_configuration" => Ok (1007u16) , "range" => Ok (1204u16) , "ping_interval" => Ok (1206u16) , "continuous_stop" => Ok (1401u16) , "gain_setting" => Ok (1207u16) , "transmit_duration" => Ok (1208u16) , "voltage_5" => Ok (1202u16) , "device_id" => Ok (1201u16) , "set_gain_setting" => Ok (1005u16) , "oss_profile_configuration" => Ok (1301u16) , "pcb_temperature" => Ok (1214u16) , "set_mode_auto" => Ok (1003u16) , "mode_auto" => Ok (1205u16) , "general_info" => Ok (1210u16) , "set_speed_of_sound" => Ok (1002u16) , "speed_of_sound" => Ok (1203u16) , "distance" => Ok (1212u16) , "set_range" => Ok (1001u16) , "profile" => Ok (1300u16) , "set_ping_enable" => Ok (1006u16) , "set_ping_interval" => Ok (1004u16) , "continuous_start" => Ok (1400u16) , "processor_temperature" => Ok (1213u16) , "ping_enable" => Ok (1215u16) , "goto_bootloader" => Ok (1100u16) , "distance_simple" => Ok (1211u16) , "set_device_id" => Ok (1000u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: FirmwareVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetOssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Range (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStop (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TransmitDuration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Voltage5 (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetGainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PcbTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralInfo (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Distance (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetRange (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Profile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStart (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProcessorTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GotoBootloader (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DistanceSimple (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 1200u16 => Messages :: FirmwareVersion (< FirmwareVersionStruct as DeserializePayload > :: deserialize (payload)) , 1007u16 => Messages :: SetOssProfileConfiguration (< SetOssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1204u16 => Messages :: Range (< RangeStruct as DeserializePayload > :: deserialize (payload)) , 1206u16 => Messages :: PingInterval (< PingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1401u16 => Messages :: ContinuousStop (< ContinuousStopStruct as DeserializePayload > :: deserialize (payload)) , 1207u16 => Messages :: GainSetting (< GainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1208u16 => Messages :: TransmitDuration (< TransmitDurationStruct as DeserializePayload > :: deserialize (payload)) , 1202u16 => Messages :: Voltage5 (< Voltage5Struct as DeserializePayload > :: deserialize (payload)) , 1201u16 => Messages :: DeviceId (< DeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1005u16 => Messages :: SetGainSetting (< SetGainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1301u16 => Messages :: OssProfileConfiguration (< OssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1214u16 => Messages :: PcbTemperature (< PcbTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1003u16 => Messages :: SetModeAuto (< SetModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1205u16 => Messages :: ModeAuto (< ModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1210u16 => Messages :: GeneralInfo (< GeneralInfoStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1203u16 => Messages :: SpeedOfSound (< SpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1212u16 => Messages :: Distance (< DistanceStruct as DeserializePayload > :: deserialize (payload)) , 1001u16 => Messages :: SetRange (< SetRangeStruct as DeserializePayload > :: deserialize (payload)) , 1300u16 => Messages :: Profile (< ProfileStruct as DeserializePayload > :: deserialize (payload)) , 1006u16 => Messages :: SetPingEnable (< SetPingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1004u16 => Messages :: SetPingInterval (< SetPingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1400u16 => Messages :: ContinuousStart (< ContinuousStartStruct as DeserializePayload > :: deserialize (payload)) , 1213u16 => Messages :: ProcessorTemperature (< ProcessorTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1215u16 => Messages :: PingEnable (< PingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1100u16 => Messages :: GotoBootloader (< GotoBootloaderStruct as DeserializePayload > :: deserialize (payload)) , 1211u16 => Messages :: DistanceSimple (< DistanceSimpleStruct as DeserializePayload > :: deserialize (payload)) , 1000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { FirmwareVersion (FirmwareVersionStruct) , SetOssProfileConfiguration (SetOssProfileConfigurationStruct) , Range (RangeStruct) , PingInterval (PingIntervalStruct) , ContinuousStop (ContinuousStopStruct) , GainSetting (GainSettingStruct) , TransmitDuration (TransmitDurationStruct) , Voltage5 (Voltage5Struct) , DeviceId (DeviceIdStruct) , SetGainSetting (SetGainSettingStruct) , OssProfileConfiguration (OssProfileConfigurationStruct) , PcbTemperature (PcbTemperatureStruct) , SetModeAuto (SetModeAutoStruct) , ModeAuto (ModeAutoStruct) , GeneralInfo (GeneralInfoStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , SpeedOfSound (SpeedOfSoundStruct) , Distance (DistanceStruct) , SetRange (SetRangeStruct) , Profile (ProfileStruct) , SetPingEnable (SetPingEnableStruct) , SetPingInterval (SetPingIntervalStruct) , ContinuousStart (ContinuousStartStruct) , ProcessorTemperature (ProcessorTemperatureStruct) , PingEnable (PingEnableStruct) , GotoBootloader (GotoBootloaderStruct) , DistanceSimple (DistanceSimpleStruct) , SetDeviceId (SetDeviceIdStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: FirmwareVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetOssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Range (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStop (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TransmitDuration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Voltage5 (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetGainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PcbTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralInfo (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Distance (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetRange (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Profile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStart (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProcessorTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GotoBootloader (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DistanceSimple (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct FirmwareVersionStruct { # [doc = "Device type. 0: Unknown; 1: Echosounder"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Echosounder"))] pub device_type : u8 , # [doc = "Device model. 0: Unknown; 1: Ping1D"] # [cfg_attr (feature = "schemars" , schemars (description = "Device model. 0: Unknown; 1: Ping1D"))] pub device_model : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u16 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u16 , } impl SerializePayload for FirmwareVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_model . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer } } impl DeserializePayload for FirmwareVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_model : payload [1usize] . into () , firmware_version_major : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for FirmwareVersionStruct { fn id () -> u16 { 1200u16 } fn name () -> & 'static str { "firmware_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the profile output configuration. (Open source firmware only)"] pub struct SetOssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for SetOssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetOssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for SetOssProfileConfigurationStruct { fn id () -> u16 { 1007u16 } fn name () -> & 'static str { "set_oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub struct RangeStruct { # [doc = "The beginning of the scan range in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan range in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan range."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range."))] pub scan_length : u32 , } impl SerializePayload for RangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for RangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for RangeStruct { fn id () -> u16 { 1204u16 } fn name () -> & 'static str { "range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct PingIntervalStruct { # [doc = "The minimum interval between acoustic measurements. The actual interval may be longer."] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum interval between acoustic measurements. The actual interval may be longer."))] pub ping_interval : u16 , } impl SerializePayload for PingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PingIntervalStruct { fn id () -> u16 { 1206u16 } fn name () -> & 'static str { "ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to stop the continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to stop the continuous data stream of profile messages."] pub struct ContinuousStopStruct { # [doc = "The message id to stop streaming. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stop streaming. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStopStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStopStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStopStruct { fn id () -> u16 { 1401u16 } fn name () -> & 'static str { "continuous_stop" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current gain setting."] pub struct GainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for GainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for GainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GainSettingStruct { fn id () -> u16 { 1207u16 } fn name () -> & 'static str { "gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The duration of the acoustic activation/transmission."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The duration of the acoustic activation/transmission."] pub struct TransmitDurationStruct { # [doc = "Acoustic pulse duration."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic pulse duration."))] pub transmit_duration : u16 , } impl SerializePayload for TransmitDurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransmitDurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { transmit_duration : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TransmitDurationStruct { fn id () -> u16 { 1208u16 } fn name () -> & 'static str { "transmit_duration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The 5V rail voltage."] pub struct Voltage5Struct { # [doc = "The 5V rail voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] pub voltage_5 : u16 , } impl SerializePayload for Voltage5Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for Voltage5Struct { fn deserialize (payload : & [u8]) -> Self { Self { voltage_5 : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for Voltage5Struct { fn id () -> u16 { 1202u16 } fn name () -> & 'static str { "voltage_5" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The device ID."] pub struct DeviceIdStruct { # [doc = "The device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for DeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for DeviceIdStruct { fn id () -> u16 { 1201u16 } fn name () -> & 'static str { "device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the current gain setting."] pub struct SetGainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , } impl SerializePayload for SetGainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetGainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : payload [0usize] . into () , } } } impl MessageInfo for SetGainSettingStruct { fn id () -> u16 { 1005u16 } fn name () -> & 'static str { "set_gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the profile output configuration. (Open source firmware only)"] pub struct OssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for OssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for OssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for OssProfileConfigurationStruct { fn id () -> u16 { 1301u16 } fn name () -> & 'static str { "oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the on-board thermistor."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the on-board thermistor."] pub struct PcbTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub pcb_temperature : u16 , } impl SerializePayload for PcbTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . pcb_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for PcbTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { pcb_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PcbTemperatureStruct { fn id () -> u16 { 1214u16 } fn name () -> & 'static str { "pcb_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] pub struct SetModeAutoStruct { # [doc = "0: manual mode. 1: auto mode."] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode. 1: auto mode."))] pub mode_auto : u8 , } impl SerializePayload for SetModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for SetModeAutoStruct { fn id () -> u16 { 1003u16 } fn name () -> & 'static str { "set_mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub struct ModeAutoStruct { # [doc = "0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for ModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for ModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for ModeAutoStruct { fn id () -> u16 { 1205u16 } fn name () -> & 'static str { "mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "General information."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "General information."] pub struct GeneralInfoStruct { # [doc = "Firmware major version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware major version."))] pub firmware_version_major : u16 , # [doc = "Firmware minor version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware minor version."))] pub firmware_version_minor : u16 , # [doc = "Device supply voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "Device supply voltage."))] pub voltage_5 : u16 , # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , # [doc = "The current operating mode of the device. 0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. 0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for GeneralInfoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralInfoStruct { fn deserialize (payload : & [u8]) -> Self { Self { firmware_version_major : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , voltage_5 : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_interval : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , gain_setting : payload [8usize] . into () , mode_auto : payload [9usize] . into () , } } } impl MessageInfo for GeneralInfoStruct { fn id () -> u16 { 1210u16 } fn name () -> & 'static str { "general_info" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound used for distance calculations."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The speed of sound used for distance calculations."] pub struct SpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SpeedOfSoundStruct { fn id () -> u16 { 1203u16 } fn name () -> & 'static str { "speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub struct DistanceStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for DistanceStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for DistanceStruct { fn id () -> u16 { 1212u16 } fn name () -> & 'static str { "distance" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the scan range for acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the scan range for acoustic measurements."] pub struct SetRangeStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub scan_start : u32 , # [doc = "The length of the scan range. Minimum 1000."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range. Minimum 1000."))] pub scan_length : u32 , } impl SerializePayload for SetRangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetRangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetRangeStruct { fn id () -> u16 { 1001u16 } fn name () -> & 'static str { "set_range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub struct ProfileStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data : Vec < u8 > , } impl SerializePayload for ProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . profile_data_length . to_le_bytes ()) ; for value in self . profile_data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for ProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , profile_data_length : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , profile_data : payload [24usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for ProfileStruct { fn id () -> u16 { 1300u16 } fn name () -> & 'static str { "profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Enable or disable acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Enable or disable acoustic measurements."] pub struct SetPingEnableStruct { # [doc = "0: Disable, 1: Enable."] # [cfg_attr (feature = "schemars" , schemars (description = "0: Disable, 1: Enable."))] pub ping_enabled : u8 , } impl SerializePayload for SetPingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for SetPingEnableStruct { fn id () -> u16 { 1006u16 } fn name () -> & 'static str { "set_ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct SetPingIntervalStruct { # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , } impl SerializePayload for SetPingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetPingIntervalStruct { fn id () -> u16 { 1004u16 } fn name () -> & 'static str { "set_ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to initiate continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to initiate continuous data stream of profile messages."] pub struct ContinuousStartStruct { # [doc = "The message id to stream. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stream. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStartStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStartStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStartStruct { fn id () -> u16 { 1400u16 } fn name () -> & 'static str { "continuous_start" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the device cpu."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the device cpu."] pub struct ProcessorTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub processor_temperature : u16 , } impl SerializePayload for ProcessorTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . processor_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProcessorTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { processor_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ProcessorTemperatureStruct { fn id () -> u16 { 1213u16 } fn name () -> & 'static str { "processor_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic output enabled state."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acoustic output enabled state."] pub struct PingEnableStruct { # [doc = "The state of the acoustic output. 0: disabled, 1:enabled"] # [cfg_attr (feature = "schemars" , schemars (description = "The state of the acoustic output. 0: disabled, 1:enabled"))] pub ping_enabled : u8 , } impl SerializePayload for PingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for PingEnableStruct { fn id () -> u16 { 1215u16 } fn name () -> & 'static str { "ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Send the device into the bootloader. This is useful for firmware updates."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Send the device into the bootloader. This is useful for firmware updates."] pub struct GotoBootloaderStruct { } impl SerializePayload for GotoBootloaderStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for GotoBootloaderStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for GotoBootloaderStruct { fn id () -> u16 { 1100u16 } fn name () -> & 'static str { "goto_bootloader" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate."] pub struct DistanceSimpleStruct { # [doc = "Distance to the target."] # [cfg_attr (feature = "schemars" , schemars (description = "Distance to the target."))] pub distance : u32 , # [doc = "Confidence in the distance measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the distance measurement."))] pub confidence : u8 , } impl SerializePayload for DistanceSimpleStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceSimpleStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : payload [4usize] . into () , } } } impl MessageInfo for DistanceSimpleStruct { fn id () -> u16 { 1211u16 } fn name () -> & 'static str { "distance_simple" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 1000u16 } fn name () -> & 'static str { "set_device_id" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Device information"] pub async fn firmware_version (& self) -> Result < FirmwareVersionStruct , PingError > { self . request () . await } # [doc = "Set the profile output configuration. (Open source firmware only)"] # [doc = "# Arguments"] # [doc = "* `number_of_points` - Not documented"] # [doc = "* `normalization_enabled` - If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [doc = "* `enhance_enabled` - If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] pub async fn set_oss_profile_configuration (& self , number_of_points : u16 , normalization_enabled : u8 , enhance_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetOssProfileConfiguration (SetOssProfileConfigurationStruct { number_of_points , normalization_enabled , enhance_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetOssProfileConfigurationStruct :: id ()) . await } # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub async fn range (& self) -> Result < RangeStruct , PingError > { self . request () . await } # [doc = "The interval between acoustic measurements."] pub async fn ping_interval (& self) -> Result < PingIntervalStruct , PingError > { self . request () . await } # [doc = "Command to stop the continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stop streaming. 1300: profile"] pub async fn continuous_stop (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStop (ContinuousStopStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The current gain setting."] pub async fn gain_setting (& self) -> Result < GainSettingStruct , PingError > { self . request () . await } # [doc = "The duration of the acoustic activation/transmission."] pub async fn transmit_duration (& self) -> Result < TransmitDurationStruct , PingError > { self . request () . await } # [doc = "The 5V rail voltage."] pub async fn voltage_5 (& self) -> Result < Voltage5Struct , PingError > { self . request () . await } # [doc = "The device ID."] pub async fn device_id (& self) -> Result < DeviceIdStruct , PingError > { self . request () . await } # [doc = "Set the current gain setting."] # [doc = "# Arguments"] # [doc = "* `gain_setting` - The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] pub async fn set_gain_setting (& self , gain_setting : u8) -> Result < () , PingError > { let request = Messages :: SetGainSetting (SetGainSettingStruct { gain_setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetGainSettingStruct :: id ()) . await } # [doc = "Get the profile output configuration. (Open source firmware only)"] pub async fn oss_profile_configuration (& self) -> Result < OssProfileConfigurationStruct , PingError > { self . request () . await } # [doc = "Temperature of the on-board thermistor."] pub async fn pcb_temperature (& self) -> Result < PcbTemperatureStruct , PingError > { self . request () . await } # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] # [doc = "# Arguments"] # [doc = "* `mode_auto` - 0: manual mode. 1: auto mode."] pub async fn set_mode_auto (& self , mode_auto : u8) -> Result < () , PingError > { let request = Messages :: SetModeAuto (SetModeAutoStruct { mode_auto , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetModeAutoStruct :: id ()) . await } # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub async fn mode_auto (& self) -> Result < ModeAutoStruct , PingError > { self . request () . await } # [doc = "General information."] pub async fn general_info (& self) -> Result < GeneralInfoStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound used for distance calculations."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetSpeedOfSoundStruct :: id ()) . await } # [doc = "The speed of sound used for distance calculations."] pub async fn speed_of_sound (& self) -> Result < SpeedOfSoundStruct , PingError > { self . request () . await } # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub async fn distance (& self) -> Result < DistanceStruct , PingError > { self . request () . await } # [doc = "Set the scan range for acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `scan_start` \\[mm\\] - Not documented"] # [doc = "* `scan_length` \\[mm\\] - The length of the scan range. Minimum 1000."] pub async fn set_range (& self , scan_start : u32 , scan_length : u32) -> Result < () , PingError > { let request = Messages :: SetRange (SetRangeStruct { scan_start , scan_length , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetRangeStruct :: id ()) . await } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub async fn profile (& self) -> Result < ProfileStruct , PingError > { self . request () . await } # [doc = "Enable or disable acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_enabled` - 0: Disable, 1: Enable."] pub async fn set_ping_enable (& self , ping_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetPingEnable (SetPingEnableStruct { ping_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingEnableStruct :: id ()) . await } # [doc = "The interval between acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_interval` \\[ms\\] - The interval between acoustic measurements."] pub async fn set_ping_interval (& self , ping_interval : u16) -> Result < () , PingError > { let request = Messages :: SetPingInterval (SetPingIntervalStruct { ping_interval , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingIntervalStruct :: id ()) . await } # [doc = "Command to initiate continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stream. 1300: profile"] pub async fn continuous_start (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStart (ContinuousStartStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Temperature of the device cpu."] pub async fn processor_temperature (& self) -> Result < ProcessorTemperatureStruct , PingError > { self . request () . await } # [doc = "Acoustic output enabled state."] pub async fn ping_enable (& self) -> Result < PingEnableStruct , PingError > { self . request () . await } # [doc = "Send the device into the bootloader. This is useful for firmware updates."] # [doc = "# Arguments"] pub async fn goto_bootloader (& self ,) -> Result < () , PingError > { let request = Messages :: GotoBootloader (GotoBootloaderStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The distance to target with confidence estimate."] pub async fn distance_simple (& self) -> Result < DistanceSimpleStruct , PingError > { self . request () . await } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (0-254). 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: FirmwareVersion (..) => "firmware_version" , Messages :: SetOssProfileConfiguration (..) => "set_oss_profile_configuration" , Messages :: Range (..) => "range" , Messages :: PingInterval (..) => "ping_interval" , Messages :: ContinuousStop (..) => "continuous_stop" , Messages :: GainSetting (..) => "gain_setting" , Messages :: TransmitDuration (..) => "transmit_duration" , Messages :: Voltage5 (..) => "voltage_5" , Messages :: DeviceId (..) => "device_id" , Messages :: SetGainSetting (..) => "set_gain_setting" , Messages :: OssProfileConfiguration (..) => "oss_profile_configuration" , Messages :: PcbTemperature (..) => "pcb_temperature" , Messages :: SetModeAuto (..) => "set_mode_auto" , Messages :: ModeAuto (..) => "mode_auto" , Messages :: GeneralInfo (..) => "general_info" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , Messages :: SpeedOfSound (..) => "speed_of_sound" , Messages :: Distance (..) => "distance" , Messages :: SetRange (..) => "set_range" , Messages :: Profile (..) => "profile" , Messages :: SetPingEnable (..) => "set_ping_enable" , Messages :: SetPingInterval (..) => "set_ping_interval" , Messages :: ContinuousStart (..) => "continuous_start" , Messages :: ProcessorTemperature (..) => "processor_temperature" , Messages :: PingEnable (..) => "ping_enable" , Messages :: GotoBootloader (..) => "goto_bootloader" , Messages :: DistanceSimple (..) => "distance_simple" , Messages :: SetDeviceId (..) => "set_device_id" , } } fn message_id (& self) -> u16 { match self { Messages :: FirmwareVersion (..) => 1200u16 , Messages :: SetOssProfileConfiguration (..) => 1007u16 , Messages :: Range (..) => 1204u16 , Messages :: PingInterval (..) => 1206u16 , Messages :: ContinuousStop (..) => 1401u16 , Messages :: GainSetting (..) => 1207u16 , Messages :: TransmitDuration (..) => 1208u16 , Messages :: Voltage5 (..) => 1202u16 , Messages :: DeviceId (..) => 1201u16 , Messages :: SetGainSetting (..) => 1005u16 , Messages :: OssProfileConfiguration (..) => 1301u16 , Messages :: PcbTemperature (..) => 1214u16 , Messages :: SetModeAuto (..) => 1003u16 , Messages :: ModeAuto (..) => 1205u16 , Messages :: GeneralInfo (..) => 1210u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , Messages :: SpeedOfSound (..) => 1203u16 , Messages :: Distance (..) => 1212u16 , Messages :: SetRange (..) => 1001u16 , Messages :: Profile (..) => 1300u16 , Messages :: SetPingEnable (..) => 1006u16 , Messages :: SetPingInterval (..) => 1004u16 , Messages :: ContinuousStart (..) => 1400u16 , Messages :: ProcessorTemperature (..) => 1213u16 , Messages :: PingEnable (..) => 1215u16 , Messages :: GotoBootloader (..) => 1100u16 , Messages :: DistanceSimple (..) => 1211u16 , Messages :: SetDeviceId (..) => 1000u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "firmware_version" => Ok (1200u16) , "set_oss_profile_configuration" => Ok (1007u16) , "range" => Ok (1204u16) , "ping_interval" => Ok (1206u16) , "continuous_stop" => Ok (1401u16) , "gain_setting" => Ok (1207u16) , "transmit_duration" => Ok (1208u16) , "voltage_5" => Ok (1202u16) , "device_id" => Ok (1201u16) , "set_gain_setting" => Ok (1005u16) , "oss_profile_configuration" => Ok (1301u16) , "pcb_temperature" => Ok (1214u16) , "set_mode_auto" => Ok (1003u16) , "mode_auto" => Ok (1205u16) , "general_info" => Ok (1210u16) , "set_speed_of_sound" => Ok (1002u16) , "speed_of_sound" => Ok (1203u16) , "distance" => Ok (1212u16) , "set_range" => Ok (1001u16) , "profile" => Ok (1300u16) , "set_ping_enable" => Ok (1006u16) , "set_ping_interval" => Ok (1004u16) , "continuous_start" => Ok (1400u16) , "processor_temperature" => Ok (1213u16) , "ping_enable" => Ok (1215u16) , "goto_bootloader" => Ok (1100u16) , "distance_simple" => Ok (1211u16) , "set_device_id" => Ok (1000u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: FirmwareVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetOssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Range (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStop (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TransmitDuration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Voltage5 (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetGainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PcbTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralInfo (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Distance (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetRange (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Profile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStart (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProcessorTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GotoBootloader (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DistanceSimple (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 1200u16 => Messages :: FirmwareVersion (< FirmwareVersionStruct as DeserializePayload > :: deserialize (payload)) , 1007u16 => Messages :: SetOssProfileConfiguration (< SetOssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1204u16 => Messages :: Range (< RangeStruct as DeserializePayload > :: deserialize (payload)) , 1206u16 => Messages :: PingInterval (< PingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1401u16 => Messages :: ContinuousStop (< ContinuousStopStruct as DeserializePayload > :: deserialize (payload)) , 1207u16 => Messages :: GainSetting (< GainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1208u16 => Messages :: TransmitDuration (< TransmitDurationStruct as DeserializePayload > :: deserialize (payload)) , 1202u16 => Messages :: Voltage5 (< Voltage5Struct as DeserializePayload > :: deserialize (payload)) , 1201u16 => Messages :: DeviceId (< DeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1005u16 => Messages :: SetGainSetting (< SetGainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1301u16 => Messages :: OssProfileConfiguration (< OssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1214u16 => Messages :: PcbTemperature (< PcbTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1003u16 => Messages :: SetModeAuto (< SetModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1205u16 => Messages :: ModeAuto (< ModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1210u16 => Messages :: GeneralInfo (< GeneralInfoStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1203u16 => Messages :: SpeedOfSound (< SpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1212u16 => Messages :: Distance (< DistanceStruct as DeserializePayload > :: deserialize (payload)) , 1001u16 => Messages :: SetRange (< SetRangeStruct as DeserializePayload > :: deserialize (payload)) , 1300u16 => Messages :: Profile (< ProfileStruct as DeserializePayload > :: deserialize (payload)) , 1006u16 => Messages :: SetPingEnable (< SetPingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1004u16 => Messages :: SetPingInterval (< SetPingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1400u16 => Messages :: ContinuousStart (< ContinuousStartStruct as DeserializePayload > :: deserialize (payload)) , 1213u16 => Messages :: ProcessorTemperature (< ProcessorTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1215u16 => Messages :: PingEnable (< PingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1100u16 => Messages :: GotoBootloader (< GotoBootloaderStruct as DeserializePayload > :: deserialize (payload)) , 1211u16 => Messages :: DistanceSimple (< DistanceSimpleStruct as DeserializePayload > :: deserialize (payload)) , 1000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { FirmwareVersion (FirmwareVersionStruct) , SetOssProfileConfiguration (SetOssProfileConfigurationStruct) , Range (RangeStruct) , PingInterval (PingIntervalStruct) , ContinuousStop (ContinuousStopStruct) , GainSetting (GainSettingStruct) , TransmitDuration (TransmitDurationStruct) , Voltage5 (Voltage5Struct) , DeviceId (DeviceIdStruct) , SetGainSetting (SetGainSettingStruct) , OssProfileConfiguration (OssProfileConfigurationStruct) , PcbTemperature (PcbTemperatureStruct) , SetModeAuto (SetModeAutoStruct) , ModeAuto (ModeAutoStruct) , GeneralInfo (GeneralInfoStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , SpeedOfSound (SpeedOfSoundStruct) , Distance (DistanceStruct) , SetRange (SetRangeStruct) , Profile (ProfileStruct) , SetPingEnable (SetPingEnableStruct) , SetPingInterval (SetPingIntervalStruct) , ContinuousStart (ContinuousStartStruct) , ProcessorTemperature (ProcessorTemperatureStruct) , PingEnable (PingEnableStruct) , GotoBootloader (GotoBootloaderStruct) , DistanceSimple (DistanceSimpleStruct) , SetDeviceId (SetDeviceIdStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: FirmwareVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetOssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Range (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStop (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TransmitDuration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Voltage5 (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetGainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PcbTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralInfo (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Distance (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetRange (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Profile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStart (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProcessorTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GotoBootloader (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DistanceSimple (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct FirmwareVersionStruct { # [doc = "Device type. 0: Unknown; 1: Echosounder"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Echosounder"))] pub device_type : u8 , # [doc = "Device model. 0: Unknown; 1: Ping1D"] # [cfg_attr (feature = "schemars" , schemars (description = "Device model. 0: Unknown; 1: Ping1D"))] pub device_model : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u16 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u16 , } impl SerializePayload for FirmwareVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_model . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer } } impl DeserializePayload for FirmwareVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : <u8 as Into<_>>::into(payload [0usize]) , device_model : payload [1usize] . into () , firmware_version_major : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for FirmwareVersionStruct { fn id () -> u16 { 1200u16 } fn name () -> & 'static str { "firmware_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the profile output configuration. (Open source firmware only)"] pub struct SetOssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for SetOssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetOssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for SetOssProfileConfigurationStruct { fn id () -> u16 { 1007u16 } fn name () -> & 'static str { "set_oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub struct RangeStruct { # [doc = "The beginning of the scan range in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan range in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan range."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range."))] pub scan_length : u32 , } impl SerializePayload for RangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for RangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for RangeStruct { fn id () -> u16 { 1204u16 } fn name () -> & 'static str { "range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct PingIntervalStruct { # [doc = "The minimum interval between acoustic measurements. The actual interval may be longer."] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum interval between acoustic measurements. The actual interval may be longer."))] pub ping_interval : u16 , } impl SerializePayload for PingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PingIntervalStruct { fn id () -> u16 { 1206u16 } fn name () -> & 'static str { "ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to stop the continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to stop the continuous data stream of profile messages."] pub struct ContinuousStopStruct { # [doc = "The message id to stop streaming. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stop streaming. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStopStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStopStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStopStruct { fn id () -> u16 { 1401u16 } fn name () -> & 'static str { "continuous_stop" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current gain setting."] pub struct GainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for GainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for GainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GainSettingStruct { fn id () -> u16 { 1207u16 } fn name () -> & 'static str { "gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The duration of the acoustic activation/transmission."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The duration of the acoustic activation/transmission."] pub struct TransmitDurationStruct { # [doc = "Acoustic pulse duration."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic pulse duration."))] pub transmit_duration : u16 , } impl SerializePayload for TransmitDurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransmitDurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { transmit_duration : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TransmitDurationStruct { fn id () -> u16 { 1208u16 } fn name () -> & 'static str { "transmit_duration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The 5V rail voltage."] pub struct Voltage5Struct { # [doc = "The 5V rail voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] pub voltage_5 : u16 , } impl SerializePayload for Voltage5Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for Voltage5Struct { fn deserialize (payload : & [u8]) -> Self { Self { voltage_5 : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for Voltage5Struct { fn id () -> u16 { 1202u16 } fn name () -> & 'static str { "voltage_5" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The device ID."] pub struct DeviceIdStruct { # [doc = "The device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for DeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for DeviceIdStruct { fn id () -> u16 { 1201u16 } fn name () -> & 'static str { "device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the current gain setting."] pub struct SetGainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , } impl SerializePayload for SetGainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetGainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : payload [0usize] . into () , } } } impl MessageInfo for SetGainSettingStruct { fn id () -> u16 { 1005u16 } fn name () -> & 'static str { "set_gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the profile output configuration. (Open source firmware only)"] pub struct OssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for OssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for OssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for OssProfileConfigurationStruct { fn id () -> u16 { 1301u16 } fn name () -> & 'static str { "oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the on-board thermistor."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the on-board thermistor."] pub struct PcbTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub pcb_temperature : u16 , } impl SerializePayload for PcbTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . pcb_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for PcbTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { pcb_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PcbTemperatureStruct { fn id () -> u16 { 1214u16 } fn name () -> & 'static str { "pcb_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] pub struct SetModeAutoStruct { # [doc = "0: manual mode. 1: auto mode."] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode. 1: auto mode."))] pub mode_auto : u8 , } impl SerializePayload for SetModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for SetModeAutoStruct { fn id () -> u16 { 1003u16 } fn name () -> & 'static str { "set_mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub struct ModeAutoStruct { # [doc = "0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for ModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for ModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for ModeAutoStruct { fn id () -> u16 { 1205u16 } fn name () -> & 'static str { "mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "General information."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "General information."] pub struct GeneralInfoStruct { # [doc = "Firmware major version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware major version."))] pub firmware_version_major : u16 , # [doc = "Firmware minor version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware minor version."))] pub firmware_version_minor : u16 , # [doc = "Device supply voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "Device supply voltage."))] pub voltage_5 : u16 , # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , # [doc = "The current operating mode of the device. 0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. 0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for GeneralInfoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralInfoStruct { fn deserialize (payload : & [u8]) -> Self { Self { firmware_version_major : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , voltage_5 : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_interval : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , gain_setting : payload [8usize] . into () , mode_auto : payload [9usize] . into () , } } } impl MessageInfo for GeneralInfoStruct { fn id () -> u16 { 1210u16 } fn name () -> & 'static str { "general_info" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound used for distance calculations."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The speed of sound used for distance calculations."] pub struct SpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SpeedOfSoundStruct { fn id () -> u16 { 1203u16 } fn name () -> & 'static str { "speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub struct DistanceStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for DistanceStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for DistanceStruct { fn id () -> u16 { 1212u16 } fn name () -> & 'static str { "distance" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the scan range for acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the scan range for acoustic measurements."] pub struct SetRangeStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub scan_start : u32 , # [doc = "The length of the scan range. Minimum 1000."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range. Minimum 1000."))] pub scan_length : u32 , } impl SerializePayload for SetRangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetRangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetRangeStruct { fn id () -> u16 { 1001u16 } fn name () -> & 'static str { "set_range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub struct ProfileStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data : Vec < u8 > , } impl SerializePayload for ProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . profile_data_length . to_le_bytes ()) ; for value in self . profile_data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for ProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , profile_data_length : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , profile_data : payload [24usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for ProfileStruct { fn id () -> u16 { 1300u16 } fn name () -> & 'static str { "profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Enable or disable acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Enable or disable acoustic measurements."] pub struct SetPingEnableStruct { # [doc = "0: Disable, 1: Enable."] # [cfg_attr (feature = "schemars" , schemars (description = "0: Disable, 1: Enable."))] pub ping_enabled : u8 , } impl SerializePayload for SetPingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for SetPingEnableStruct { fn id () -> u16 { 1006u16 } fn name () -> & 'static str { "set_ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct SetPingIntervalStruct { # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , } impl SerializePayload for SetPingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetPingIntervalStruct { fn id () -> u16 { 1004u16 } fn name () -> & 'static str { "set_ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to initiate continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to initiate continuous data stream of profile messages."] pub struct ContinuousStartStruct { # [doc = "The message id to stream. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stream. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStartStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStartStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStartStruct { fn id () -> u16 { 1400u16 } fn name () -> & 'static str { "continuous_start" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the device cpu."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the device cpu."] pub struct ProcessorTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub processor_temperature : u16 , } impl SerializePayload for ProcessorTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . processor_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProcessorTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { processor_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ProcessorTemperatureStruct { fn id () -> u16 { 1213u16 } fn name () -> & 'static str { "processor_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic output enabled state."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acoustic output enabled state."] pub struct PingEnableStruct { # [doc = "The state of the acoustic output. 0: disabled, 1:enabled"] # [cfg_attr (feature = "schemars" , schemars (description = "The state of the acoustic output. 0: disabled, 1:enabled"))] pub ping_enabled : u8 , } impl SerializePayload for PingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for PingEnableStruct { fn id () -> u16 { 1215u16 } fn name () -> & 'static str { "ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Send the device into the bootloader. This is useful for firmware updates."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Send the device into the bootloader. This is useful for firmware updates."] pub struct GotoBootloaderStruct { } impl SerializePayload for GotoBootloaderStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for GotoBootloaderStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for GotoBootloaderStruct { fn id () -> u16 { 1100u16 } fn name () -> & 'static str { "goto_bootloader" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate."] pub struct DistanceSimpleStruct { # [doc = "Distance to the target."] # [cfg_attr (feature = "schemars" , schemars (description = "Distance to the target."))] pub distance : u32 , # [doc = "Confidence in the distance measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the distance measurement."))] pub confidence : u8 , } impl SerializePayload for DistanceSimpleStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceSimpleStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : payload [4usize] . into () , } } } impl MessageInfo for DistanceSimpleStruct { fn id () -> u16 { 1211u16 } fn name () -> & 'static str { "distance_simple" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 1000u16 } fn name () -> & 'static str { "set_device_id" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Device information"] pub async fn firmware_version (& self) -> Result < FirmwareVersionStruct , PingError > { self . request () . await } # [doc = "Set the profile output configuration. (Open source firmware only)"] # [doc = "# Arguments"] # [doc = "* `number_of_points` - Not documented"] # [doc = "* `normalization_enabled` - If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [doc = "* `enhance_enabled` - If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] pub async fn set_oss_profile_configuration (& self , number_of_points : u16 , normalization_enabled : u8 , enhance_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetOssProfileConfiguration (SetOssProfileConfigurationStruct { number_of_points , normalization_enabled , enhance_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetOssProfileConfigurationStruct :: id ()) . await } # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub async fn range (& self) -> Result < RangeStruct , PingError > { self . request () . await } # [doc = "The interval between acoustic measurements."] pub async fn ping_interval (& self) -> Result < PingIntervalStruct , PingError > { self . request () . await } # [doc = "Command to stop the continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stop streaming. 1300: profile"] pub async fn continuous_stop (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStop (ContinuousStopStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The current gain setting."] pub async fn gain_setting (& self) -> Result < GainSettingStruct , PingError > { self . request () . await } # [doc = "The duration of the acoustic activation/transmission."] pub async fn transmit_duration (& self) -> Result < TransmitDurationStruct , PingError > { self . request () . await } # [doc = "The 5V rail voltage."] pub async fn voltage_5 (& self) -> Result < Voltage5Struct , PingError > { self . request () . await } # [doc = "The device ID."] pub async fn device_id (& self) -> Result < DeviceIdStruct , PingError > { self . request () . await } # [doc = "Set the current gain setting."] # [doc = "# Arguments"] # [doc = "* `gain_setting` - The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] pub async fn set_gain_setting (& self , gain_setting : u8) -> Result < () , PingError > { let request = Messages :: SetGainSetting (SetGainSettingStruct { gain_setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetGainSettingStruct :: id ()) . await } # [doc = "Get the profile output configuration. (Open source firmware only)"] pub async fn oss_profile_configuration (& self) -> Result < OssProfileConfigurationStruct , PingError > { self . request () . await } # [doc = "Temperature of the on-board thermistor."] pub async fn pcb_temperature (& self) -> Result < PcbTemperatureStruct , PingError > { self . request () . await } # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] # [doc = "# Arguments"] # [doc = "* `mode_auto` - 0: manual mode. 1: auto mode."] pub async fn set_mode_auto (& self , mode_auto : u8) -> Result < () , PingError > { let request = Messages :: SetModeAuto (SetModeAutoStruct { mode_auto , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetModeAutoStruct :: id ()) . await } # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub async fn mode_auto (& self) -> Result < ModeAutoStruct , PingError > { self . request () . await } # [doc = "General information."] pub async fn general_info (& self) -> Result < GeneralInfoStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound used for distance calculations."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetSpeedOfSoundStruct :: id ()) . await } # [doc = "The speed of sound used for distance calculations."] pub async fn speed_of_sound (& self) -> Result < SpeedOfSoundStruct , PingError > { self . request () . await } # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub async fn distance (& self) -> Result < DistanceStruct , PingError > { self . request () . await } # [doc = "Set the scan range for acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `scan_start` \\[mm\\] - Not documented"] # [doc = "* `scan_length` \\[mm\\] - The length of the scan range. Minimum 1000."] pub async fn set_range (& self , scan_start : u32 , scan_length : u32) -> Result < () , PingError > { let request = Messages :: SetRange (SetRangeStruct { scan_start , scan_length , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetRangeStruct :: id ()) . await } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub async fn profile (& self) -> Result < ProfileStruct , PingError > { self . request () . await } # [doc = "Enable or disable acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_enabled` - 0: Disable, 1: Enable."] pub async fn set_ping_enable (& self , ping_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetPingEnable (SetPingEnableStruct { ping_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingEnableStruct :: id ()) . await } # [doc = "The interval between acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_interval` \\[ms\\] - The interval between acoustic measurements."] pub async fn set_ping_interval (& self , ping_interval : u16) -> Result < () , PingError > { let request = Messages :: SetPingInterval (SetPingIntervalStruct { ping_interval , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingIntervalStruct :: id ()) . await } # [doc = "Command to initiate continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stream. 1300: profile"] pub async fn continuous_start (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStart (ContinuousStartStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Temperature of the device cpu."] pub async fn processor_temperature (& self) -> Result < ProcessorTemperatureStruct , PingError > { self . request () . await } # [doc = "Acoustic output enabled state."] pub async fn ping_enable (& self) -> Result < PingEnableStruct , PingError > { self . request () . await } # [doc = "Send the device into the bootloader. This is useful for firmware updates."] # [doc = "# Arguments"] pub async fn goto_bootloader (& self ,) -> Result < () , PingError > { let request = Messages :: GotoBootloader (GotoBootloaderStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The distance to target with confidence estimate."] pub async fn distance_simple (& self) -> Result < DistanceSimpleStruct , PingError > { self . request () . await } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (0-254). 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: FirmwareVersion (..) => "firmware_version" , Messages :: SetOssProfileConfiguration (..) => "set_oss_profile_configuration" , Messages :: Range (..) => "range" , Messages :: PingInterval (..) => "ping_interval" , Messages :: ContinuousStop (..) => "continuous_stop" , Messages :: GainSetting (..) => "gain_setting" , Messages :: TransmitDuration (..) => "transmit_duration" , Messages :: Voltage5 (..) => "voltage_5" , Messages :: DeviceId (..) => "device_id" , Messages :: SetGainSetting (..) => "set_gain_setting" , Messages :: OssProfileConfiguration (..) => "oss_profile_configuration" , Messages :: PcbTemperature (..) => "pcb_temperature" , Messages :: SetModeAuto (..) => "set_mode_auto" , Messages :: ModeAuto (..) => "mode_auto" , Messages :: GeneralInfo (..) => "general_info" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , Messages :: SpeedOfSound (..) => "speed_of_sound" , Messages :: Distance (..) => "distance" , Messages :: SetRange (..) => "set_range" , Messages :: Profile (..) => "profile" , Messages :: SetPingEnable (..) => "set_ping_enable" , Messages :: SetPingInterval (..) => "set_ping_interval" , Messages :: ContinuousStart (..) => "continuous_start" , Messages :: ProcessorTemperature (..) => "processor_temperature" , Messages :: PingEnable (..) => "ping_enable" , Messages :: GotoBootloader (..) => "goto_bootloader" , Messages :: DistanceSimple (..) => "distance_simple" , Messages :: SetDeviceId (..) => "set_device_id" , } } fn message_id (& self) -> u16 { match self { Messages :: FirmwareVersion (..) => 1200u16 , Messages :: SetOssProfileConfiguration (..) => 1007u16 , Messages :: Range (..) => 1204u16 , Messages :: PingInterval (..) => 1206u16 , Messages :: ContinuousStop (..) => 1401u16 , Messages :: GainSetting (..) => 1207u16 , Messages :: TransmitDuration (..) => 1208u16 , Messages :: Voltage5 (..) => 1202u16 , Messages :: DeviceId (..) => 1201u16 , Messages :: SetGainSetting (..) => 1005u16 , Messages :: OssProfileConfiguration (..) => 1301u16 , Messages :: PcbTemperature (..) => 1214u16 , Messages :: SetModeAuto (..) => 1003u16 , Messages :: ModeAuto (..) => 1205u16 , Messages :: GeneralInfo (..) => 1210u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , Messages :: SpeedOfSound (..) => 1203u16 , Messages :: Distance (..) => 1212u16 , Messages :: SetRange (..) => 1001u16 , Messages :: Profile (..) => 1300u16 , Messages :: SetPingEnable (..) => 1006u16 , Messages :: SetPingInterval (..) => 1004u16 , Messages :: ContinuousStart (..) => 1400u16 , Messages :: ProcessorTemperature (..) => 1213u16 , Messages :: PingEnable (..) => 1215u16 , Messages :: GotoBootloader (..) => 1100u16 , Messages :: DistanceSimple (..) => 1211u16 , Messages :: SetDeviceId (..) => 1000u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "firmware_version" => Ok (1200u16) , "set_oss_profile_configuration" => Ok (1007u16) , "range" => Ok (1204u16) , "ping_interval" => Ok (1206u16) , "continuous_stop" => Ok (1401u16) , "gain_setting" => Ok (1207u16) , "transmit_duration" => Ok (1208u16) , "voltage_5" => Ok (1202u16) , "device_id" => Ok (1201u16) , "set_gain_setting" => Ok (1005u16) , "oss_profile_configuration" => Ok (1301u16) , "pcb_temperature" => Ok (1214u16) , "set_mode_auto" => Ok (1003u16) , "mode_auto" => Ok (1205u16) , "general_info" => Ok (1210u16) , "set_speed_of_sound" => Ok (1002u16) , "speed_of_sound" => Ok (1203u16) , "distance" => Ok (1212u16) , "set_range" => Ok (1001u16) , "profile" => Ok (1300u16) , "set_ping_enable" => Ok (1006u16) , "set_ping_interval" => Ok (1004u16) , "continuous_start" => Ok (1400u16) , "processor_temperature" => Ok (1213u16) , "ping_enable" => Ok (1215u16) , "goto_bootloader" => Ok (1100u16) , "distance_simple" => Ok (1211u16) , "set_device_id" => Ok (1000u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: FirmwareVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetOssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Range (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStop (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TransmitDuration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Voltage5 (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetGainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PcbTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralInfo (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Distance (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetRange (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Profile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStart (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProcessorTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GotoBootloader (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DistanceSimple (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 1200u16 => Messages :: FirmwareVersion (< FirmwareVersionStruct as DeserializePayload > :: deserialize (payload)) , 1007u16 => Messages :: SetOssProfileConfiguration (< SetOssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1204u16 => Messages :: Range (< RangeStruct as DeserializePayload > :: deserialize (payload)) , 1206u16 => Messages :: PingInterval (< PingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1401u16 => Messages :: ContinuousStop (< ContinuousStopStruct as DeserializePayload > :: deserialize (payload)) , 1207u16 => Messages :: GainSetting (< GainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1208u16 => Messages :: TransmitDuration (< TransmitDurationStruct as DeserializePayload > :: deserialize (payload)) , 1202u16 => Messages :: Voltage5 (< Voltage5Struct as DeserializePayload > :: deserialize (payload)) , 1201u16 => Messages :: DeviceId (< DeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1005u16 => Messages :: SetGainSetting (< SetGainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1301u16 => Messages :: OssProfileConfiguration (< OssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1214u16 => Messages :: PcbTemperature (< PcbTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1003u16 => Messages :: SetModeAuto (< SetModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1205u16 => Messages :: ModeAuto (< ModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1210u16 => Messages :: GeneralInfo (< GeneralInfoStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1203u16 => Messages :: SpeedOfSound (< SpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1212u16 => Messages :: Distance (< DistanceStruct as DeserializePayload > :: deserialize (payload)) , 1001u16 => Messages :: SetRange (< SetRangeStruct as DeserializePayload > :: deserialize (payload)) , 1300u16 => Messages :: Profile (< ProfileStruct as DeserializePayload > :: deserialize (payload)) , 1006u16 => Messages :: SetPingEnable (< SetPingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1004u16 => Messages :: SetPingInterval (< SetPingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1400u16 => Messages :: ContinuousStart (< ContinuousStartStruct as DeserializePayload > :: deserialize (payload)) , 1213u16 => Messages :: ProcessorTemperature (< ProcessorTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1215u16 => Messages :: PingEnable (< PingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1100u16 => Messages :: GotoBootloader (< GotoBootloaderStruct as DeserializePayload > :: deserialize (payload)) , 1211u16 => Messages :: DistanceSimple (< DistanceSimpleStruct as DeserializePayload > :: deserialize (payload)) , 1000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] 
[INFO] [stdout] 
[INFO] [stdout] error: useless conversion to the same type: `u8` bluerobotics_ping
[INFO] [stdout]  --> /opt/rustwide/target/debug/build/bluerobotics-ping/66c034e72b565a74/out/ping1d.rs:1:7289
[INFO] [stdout]   |
[INFO] [stdout] 1 | ..._type : payload [0usize] . into () , device_model : payload [1usize] . into () , firmware_version_major : u16 :: from_le_bytes (pa...
[INFO] [stdout]   |                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^
[INFO] [stdout]   |
[INFO] [stdout]   = note: this method call relies on the `impl<T> Into<T> for T` blanket implementation and type inference, which is a semver hazard as a new `impl Into<_>` that affects your type might be added in the future causing type inference errors
[INFO] [stdout] help: consider removing the conversion call
[INFO] [stdout]   |
[INFO] [stdout] 1 - use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { FirmwareVersion (FirmwareVersionStruct) , SetOssProfileConfiguration (SetOssProfileConfigurationStruct) , Range (RangeStruct) , PingInterval (PingIntervalStruct) , ContinuousStop (ContinuousStopStruct) , GainSetting (GainSettingStruct) , TransmitDuration (TransmitDurationStruct) , Voltage5 (Voltage5Struct) , DeviceId (DeviceIdStruct) , SetGainSetting (SetGainSettingStruct) , OssProfileConfiguration (OssProfileConfigurationStruct) , PcbTemperature (PcbTemperatureStruct) , SetModeAuto (SetModeAutoStruct) , ModeAuto (ModeAutoStruct) , GeneralInfo (GeneralInfoStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , SpeedOfSound (SpeedOfSoundStruct) , Distance (DistanceStruct) , SetRange (SetRangeStruct) , Profile (ProfileStruct) , SetPingEnable (SetPingEnableStruct) , SetPingInterval (SetPingIntervalStruct) , ContinuousStart (ContinuousStartStruct) , ProcessorTemperature (ProcessorTemperatureStruct) , PingEnable (PingEnableStruct) , GotoBootloader (GotoBootloaderStruct) , DistanceSimple (DistanceSimpleStruct) , SetDeviceId (SetDeviceIdStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: FirmwareVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetOssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Range (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStop (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TransmitDuration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Voltage5 (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetGainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PcbTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralInfo (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Distance (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetRange (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Profile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStart (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProcessorTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GotoBootloader (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DistanceSimple (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct FirmwareVersionStruct { # [doc = "Device type. 0: Unknown; 1: Echosounder"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Echosounder"))] pub device_type : u8 , # [doc = "Device model. 0: Unknown; 1: Ping1D"] # [cfg_attr (feature = "schemars" , schemars (description = "Device model. 0: Unknown; 1: Ping1D"))] pub device_model : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u16 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u16 , } impl SerializePayload for FirmwareVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_model . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer } } impl DeserializePayload for FirmwareVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_model : payload [1usize] . into () , firmware_version_major : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for FirmwareVersionStruct { fn id () -> u16 { 1200u16 } fn name () -> & 'static str { "firmware_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the profile output configuration. (Open source firmware only)"] pub struct SetOssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for SetOssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetOssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for SetOssProfileConfigurationStruct { fn id () -> u16 { 1007u16 } fn name () -> & 'static str { "set_oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub struct RangeStruct { # [doc = "The beginning of the scan range in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan range in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan range."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range."))] pub scan_length : u32 , } impl SerializePayload for RangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for RangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for RangeStruct { fn id () -> u16 { 1204u16 } fn name () -> & 'static str { "range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct PingIntervalStruct { # [doc = "The minimum interval between acoustic measurements. The actual interval may be longer."] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum interval between acoustic measurements. The actual interval may be longer."))] pub ping_interval : u16 , } impl SerializePayload for PingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PingIntervalStruct { fn id () -> u16 { 1206u16 } fn name () -> & 'static str { "ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to stop the continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to stop the continuous data stream of profile messages."] pub struct ContinuousStopStruct { # [doc = "The message id to stop streaming. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stop streaming. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStopStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStopStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStopStruct { fn id () -> u16 { 1401u16 } fn name () -> & 'static str { "continuous_stop" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current gain setting."] pub struct GainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for GainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for GainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GainSettingStruct { fn id () -> u16 { 1207u16 } fn name () -> & 'static str { "gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The duration of the acoustic activation/transmission."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The duration of the acoustic activation/transmission."] pub struct TransmitDurationStruct { # [doc = "Acoustic pulse duration."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic pulse duration."))] pub transmit_duration : u16 , } impl SerializePayload for TransmitDurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransmitDurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { transmit_duration : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TransmitDurationStruct { fn id () -> u16 { 1208u16 } fn name () -> & 'static str { "transmit_duration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The 5V rail voltage."] pub struct Voltage5Struct { # [doc = "The 5V rail voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] pub voltage_5 : u16 , } impl SerializePayload for Voltage5Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for Voltage5Struct { fn deserialize (payload : & [u8]) -> Self { Self { voltage_5 : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for Voltage5Struct { fn id () -> u16 { 1202u16 } fn name () -> & 'static str { "voltage_5" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The device ID."] pub struct DeviceIdStruct { # [doc = "The device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for DeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for DeviceIdStruct { fn id () -> u16 { 1201u16 } fn name () -> & 'static str { "device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the current gain setting."] pub struct SetGainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , } impl SerializePayload for SetGainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetGainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : payload [0usize] . into () , } } } impl MessageInfo for SetGainSettingStruct { fn id () -> u16 { 1005u16 } fn name () -> & 'static str { "set_gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the profile output configuration. (Open source firmware only)"] pub struct OssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for OssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for OssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for OssProfileConfigurationStruct { fn id () -> u16 { 1301u16 } fn name () -> & 'static str { "oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the on-board thermistor."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the on-board thermistor."] pub struct PcbTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub pcb_temperature : u16 , } impl SerializePayload for PcbTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . pcb_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for PcbTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { pcb_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PcbTemperatureStruct { fn id () -> u16 { 1214u16 } fn name () -> & 'static str { "pcb_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] pub struct SetModeAutoStruct { # [doc = "0: manual mode. 1: auto mode."] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode. 1: auto mode."))] pub mode_auto : u8 , } impl SerializePayload for SetModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for SetModeAutoStruct { fn id () -> u16 { 1003u16 } fn name () -> & 'static str { "set_mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub struct ModeAutoStruct { # [doc = "0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for ModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for ModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for ModeAutoStruct { fn id () -> u16 { 1205u16 } fn name () -> & 'static str { "mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "General information."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "General information."] pub struct GeneralInfoStruct { # [doc = "Firmware major version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware major version."))] pub firmware_version_major : u16 , # [doc = "Firmware minor version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware minor version."))] pub firmware_version_minor : u16 , # [doc = "Device supply voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "Device supply voltage."))] pub voltage_5 : u16 , # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , # [doc = "The current operating mode of the device. 0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. 0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for GeneralInfoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralInfoStruct { fn deserialize (payload : & [u8]) -> Self { Self { firmware_version_major : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , voltage_5 : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_interval : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , gain_setting : payload [8usize] . into () , mode_auto : payload [9usize] . into () , } } } impl MessageInfo for GeneralInfoStruct { fn id () -> u16 { 1210u16 } fn name () -> & 'static str { "general_info" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound used for distance calculations."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The speed of sound used for distance calculations."] pub struct SpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SpeedOfSoundStruct { fn id () -> u16 { 1203u16 } fn name () -> & 'static str { "speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub struct DistanceStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for DistanceStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for DistanceStruct { fn id () -> u16 { 1212u16 } fn name () -> & 'static str { "distance" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the scan range for acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the scan range for acoustic measurements."] pub struct SetRangeStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub scan_start : u32 , # [doc = "The length of the scan range. Minimum 1000."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range. Minimum 1000."))] pub scan_length : u32 , } impl SerializePayload for SetRangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetRangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetRangeStruct { fn id () -> u16 { 1001u16 } fn name () -> & 'static str { "set_range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub struct ProfileStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data : Vec < u8 > , } impl SerializePayload for ProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . profile_data_length . to_le_bytes ()) ; for value in self . profile_data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for ProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , profile_data_length : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , profile_data : payload [24usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for ProfileStruct { fn id () -> u16 { 1300u16 } fn name () -> & 'static str { "profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Enable or disable acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Enable or disable acoustic measurements."] pub struct SetPingEnableStruct { # [doc = "0: Disable, 1: Enable."] # [cfg_attr (feature = "schemars" , schemars (description = "0: Disable, 1: Enable."))] pub ping_enabled : u8 , } impl SerializePayload for SetPingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for SetPingEnableStruct { fn id () -> u16 { 1006u16 } fn name () -> & 'static str { "set_ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct SetPingIntervalStruct { # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , } impl SerializePayload for SetPingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetPingIntervalStruct { fn id () -> u16 { 1004u16 } fn name () -> & 'static str { "set_ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to initiate continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to initiate continuous data stream of profile messages."] pub struct ContinuousStartStruct { # [doc = "The message id to stream. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stream. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStartStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStartStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStartStruct { fn id () -> u16 { 1400u16 } fn name () -> & 'static str { "continuous_start" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the device cpu."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the device cpu."] pub struct ProcessorTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub processor_temperature : u16 , } impl SerializePayload for ProcessorTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . processor_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProcessorTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { processor_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ProcessorTemperatureStruct { fn id () -> u16 { 1213u16 } fn name () -> & 'static str { "processor_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic output enabled state."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acoustic output enabled state."] pub struct PingEnableStruct { # [doc = "The state of the acoustic output. 0: disabled, 1:enabled"] # [cfg_attr (feature = "schemars" , schemars (description = "The state of the acoustic output. 0: disabled, 1:enabled"))] pub ping_enabled : u8 , } impl SerializePayload for PingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for PingEnableStruct { fn id () -> u16 { 1215u16 } fn name () -> & 'static str { "ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Send the device into the bootloader. This is useful for firmware updates."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Send the device into the bootloader. This is useful for firmware updates."] pub struct GotoBootloaderStruct { } impl SerializePayload for GotoBootloaderStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for GotoBootloaderStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for GotoBootloaderStruct { fn id () -> u16 { 1100u16 } fn name () -> & 'static str { "goto_bootloader" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate."] pub struct DistanceSimpleStruct { # [doc = "Distance to the target."] # [cfg_attr (feature = "schemars" , schemars (description = "Distance to the target."))] pub distance : u32 , # [doc = "Confidence in the distance measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the distance measurement."))] pub confidence : u8 , } impl SerializePayload for DistanceSimpleStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceSimpleStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : payload [4usize] . into () , } } } impl MessageInfo for DistanceSimpleStruct { fn id () -> u16 { 1211u16 } fn name () -> & 'static str { "distance_simple" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 1000u16 } fn name () -> & 'static str { "set_device_id" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Device information"] pub async fn firmware_version (& self) -> Result < FirmwareVersionStruct , PingError > { self . request () . await } # [doc = "Set the profile output configuration. (Open source firmware only)"] # [doc = "# Arguments"] # [doc = "* `number_of_points` - Not documented"] # [doc = "* `normalization_enabled` - If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [doc = "* `enhance_enabled` - If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] pub async fn set_oss_profile_configuration (& self , number_of_points : u16 , normalization_enabled : u8 , enhance_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetOssProfileConfiguration (SetOssProfileConfigurationStruct { number_of_points , normalization_enabled , enhance_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetOssProfileConfigurationStruct :: id ()) . await } # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub async fn range (& self) -> Result < RangeStruct , PingError > { self . request () . await } # [doc = "The interval between acoustic measurements."] pub async fn ping_interval (& self) -> Result < PingIntervalStruct , PingError > { self . request () . await } # [doc = "Command to stop the continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stop streaming. 1300: profile"] pub async fn continuous_stop (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStop (ContinuousStopStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The current gain setting."] pub async fn gain_setting (& self) -> Result < GainSettingStruct , PingError > { self . request () . await } # [doc = "The duration of the acoustic activation/transmission."] pub async fn transmit_duration (& self) -> Result < TransmitDurationStruct , PingError > { self . request () . await } # [doc = "The 5V rail voltage."] pub async fn voltage_5 (& self) -> Result < Voltage5Struct , PingError > { self . request () . await } # [doc = "The device ID."] pub async fn device_id (& self) -> Result < DeviceIdStruct , PingError > { self . request () . await } # [doc = "Set the current gain setting."] # [doc = "# Arguments"] # [doc = "* `gain_setting` - The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] pub async fn set_gain_setting (& self , gain_setting : u8) -> Result < () , PingError > { let request = Messages :: SetGainSetting (SetGainSettingStruct { gain_setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetGainSettingStruct :: id ()) . await } # [doc = "Get the profile output configuration. (Open source firmware only)"] pub async fn oss_profile_configuration (& self) -> Result < OssProfileConfigurationStruct , PingError > { self . request () . await } # [doc = "Temperature of the on-board thermistor."] pub async fn pcb_temperature (& self) -> Result < PcbTemperatureStruct , PingError > { self . request () . await } # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] # [doc = "# Arguments"] # [doc = "* `mode_auto` - 0: manual mode. 1: auto mode."] pub async fn set_mode_auto (& self , mode_auto : u8) -> Result < () , PingError > { let request = Messages :: SetModeAuto (SetModeAutoStruct { mode_auto , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetModeAutoStruct :: id ()) . await } # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub async fn mode_auto (& self) -> Result < ModeAutoStruct , PingError > { self . request () . await } # [doc = "General information."] pub async fn general_info (& self) -> Result < GeneralInfoStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound used for distance calculations."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetSpeedOfSoundStruct :: id ()) . await } # [doc = "The speed of sound used for distance calculations."] pub async fn speed_of_sound (& self) -> Result < SpeedOfSoundStruct , PingError > { self . request () . await } # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub async fn distance (& self) -> Result < DistanceStruct , PingError > { self . request () . await } # [doc = "Set the scan range for acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `scan_start` \\[mm\\] - Not documented"] # [doc = "* `scan_length` \\[mm\\] - The length of the scan range. Minimum 1000."] pub async fn set_range (& self , scan_start : u32 , scan_length : u32) -> Result < () , PingError > { let request = Messages :: SetRange (SetRangeStruct { scan_start , scan_length , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetRangeStruct :: id ()) . await } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub async fn profile (& self) -> Result < ProfileStruct , PingError > { self . request () . await } # [doc = "Enable or disable acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_enabled` - 0: Disable, 1: Enable."] pub async fn set_ping_enable (& self , ping_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetPingEnable (SetPingEnableStruct { ping_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingEnableStruct :: id ()) . await } # [doc = "The interval between acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_interval` \\[ms\\] - The interval between acoustic measurements."] pub async fn set_ping_interval (& self , ping_interval : u16) -> Result < () , PingError > { let request = Messages :: SetPingInterval (SetPingIntervalStruct { ping_interval , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingIntervalStruct :: id ()) . await } # [doc = "Command to initiate continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stream. 1300: profile"] pub async fn continuous_start (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStart (ContinuousStartStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Temperature of the device cpu."] pub async fn processor_temperature (& self) -> Result < ProcessorTemperatureStruct , PingError > { self . request () . await } # [doc = "Acoustic output enabled state."] pub async fn ping_enable (& self) -> Result < PingEnableStruct , PingError > { self . request () . await } # [doc = "Send the device into the bootloader. This is useful for firmware updates."] # [doc = "# Arguments"] pub async fn goto_bootloader (& self ,) -> Result < () , PingError > { let request = Messages :: GotoBootloader (GotoBootloaderStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The distance to target with confidence estimate."] pub async fn distance_simple (& self) -> Result < DistanceSimpleStruct , PingError > { self . request () . await } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (0-254). 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: FirmwareVersion (..) => "firmware_version" , Messages :: SetOssProfileConfiguration (..) => "set_oss_profile_configuration" , Messages :: Range (..) => "range" , Messages :: PingInterval (..) => "ping_interval" , Messages :: ContinuousStop (..) => "continuous_stop" , Messages :: GainSetting (..) => "gain_setting" , Messages :: TransmitDuration (..) => "transmit_duration" , Messages :: Voltage5 (..) => "voltage_5" , Messages :: DeviceId (..) => "device_id" , Messages :: SetGainSetting (..) => "set_gain_setting" , Messages :: OssProfileConfiguration (..) => "oss_profile_configuration" , Messages :: PcbTemperature (..) => "pcb_temperature" , Messages :: SetModeAuto (..) => "set_mode_auto" , Messages :: ModeAuto (..) => "mode_auto" , Messages :: GeneralInfo (..) => "general_info" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , Messages :: SpeedOfSound (..) => "speed_of_sound" , Messages :: Distance (..) => "distance" , Messages :: SetRange (..) => "set_range" , Messages :: Profile (..) => "profile" , Messages :: SetPingEnable (..) => "set_ping_enable" , Messages :: SetPingInterval (..) => "set_ping_interval" , Messages :: ContinuousStart (..) => "continuous_start" , Messages :: ProcessorTemperature (..) => "processor_temperature" , Messages :: PingEnable (..) => "ping_enable" , Messages :: GotoBootloader (..) => "goto_bootloader" , Messages :: DistanceSimple (..) => "distance_simple" , Messages :: SetDeviceId (..) => "set_device_id" , } } fn message_id (& self) -> u16 { match self { Messages :: FirmwareVersion (..) => 1200u16 , Messages :: SetOssProfileConfiguration (..) => 1007u16 , Messages :: Range (..) => 1204u16 , Messages :: PingInterval (..) => 1206u16 , Messages :: ContinuousStop (..) => 1401u16 , Messages :: GainSetting (..) => 1207u16 , Messages :: TransmitDuration (..) => 1208u16 , Messages :: Voltage5 (..) => 1202u16 , Messages :: DeviceId (..) => 1201u16 , Messages :: SetGainSetting (..) => 1005u16 , Messages :: OssProfileConfiguration (..) => 1301u16 , Messages :: PcbTemperature (..) => 1214u16 , Messages :: SetModeAuto (..) => 1003u16 , Messages :: ModeAuto (..) => 1205u16 , Messages :: GeneralInfo (..) => 1210u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , Messages :: SpeedOfSound (..) => 1203u16 , Messages :: Distance (..) => 1212u16 , Messages :: SetRange (..) => 1001u16 , Messages :: Profile (..) => 1300u16 , Messages :: SetPingEnable (..) => 1006u16 , Messages :: SetPingInterval (..) => 1004u16 , Messages :: ContinuousStart (..) => 1400u16 , Messages :: ProcessorTemperature (..) => 1213u16 , Messages :: PingEnable (..) => 1215u16 , Messages :: GotoBootloader (..) => 1100u16 , Messages :: DistanceSimple (..) => 1211u16 , Messages :: SetDeviceId (..) => 1000u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "firmware_version" => Ok (1200u16) , "set_oss_profile_configuration" => Ok (1007u16) , "range" => Ok (1204u16) , "ping_interval" => Ok (1206u16) , "continuous_stop" => Ok (1401u16) , "gain_setting" => Ok (1207u16) , "transmit_duration" => Ok (1208u16) , "voltage_5" => Ok (1202u16) , "device_id" => Ok (1201u16) , "set_gain_setting" => Ok (1005u16) , "oss_profile_configuration" => Ok (1301u16) , "pcb_temperature" => Ok (1214u16) , "set_mode_auto" => Ok (1003u16) , "mode_auto" => Ok (1205u16) , "general_info" => Ok (1210u16) , "set_speed_of_sound" => Ok (1002u16) , "speed_of_sound" => Ok (1203u16) , "distance" => Ok (1212u16) , "set_range" => Ok (1001u16) , "profile" => Ok (1300u16) , "set_ping_enable" => Ok (1006u16) , "set_ping_interval" => Ok (1004u16) , "continuous_start" => Ok (1400u16) , "processor_temperature" => Ok (1213u16) , "ping_enable" => Ok (1215u16) , "goto_bootloader" => Ok (1100u16) , "distance_simple" => Ok (1211u16) , "set_device_id" => Ok (1000u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: FirmwareVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetOssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Range (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStop (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TransmitDuration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Voltage5 (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetGainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PcbTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralInfo (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Distance (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetRange (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Profile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStart (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProcessorTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GotoBootloader (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DistanceSimple (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 1200u16 => Messages :: FirmwareVersion (< FirmwareVersionStruct as DeserializePayload > :: deserialize (payload)) , 1007u16 => Messages :: SetOssProfileConfiguration (< SetOssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1204u16 => Messages :: Range (< RangeStruct as DeserializePayload > :: deserialize (payload)) , 1206u16 => Messages :: PingInterval (< PingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1401u16 => Messages :: ContinuousStop (< ContinuousStopStruct as DeserializePayload > :: deserialize (payload)) , 1207u16 => Messages :: GainSetting (< GainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1208u16 => Messages :: TransmitDuration (< TransmitDurationStruct as DeserializePayload > :: deserialize (payload)) , 1202u16 => Messages :: Voltage5 (< Voltage5Struct as DeserializePayload > :: deserialize (payload)) , 1201u16 => Messages :: DeviceId (< DeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1005u16 => Messages :: SetGainSetting (< SetGainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1301u16 => Messages :: OssProfileConfiguration (< OssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1214u16 => Messages :: PcbTemperature (< PcbTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1003u16 => Messages :: SetModeAuto (< SetModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1205u16 => Messages :: ModeAuto (< ModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1210u16 => Messages :: GeneralInfo (< GeneralInfoStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1203u16 => Messages :: SpeedOfSound (< SpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1212u16 => Messages :: Distance (< DistanceStruct as DeserializePayload > :: deserialize (payload)) , 1001u16 => Messages :: SetRange (< SetRangeStruct as DeserializePayload > :: deserialize (payload)) , 1300u16 => Messages :: Profile (< ProfileStruct as DeserializePayload > :: deserialize (payload)) , 1006u16 => Messages :: SetPingEnable (< SetPingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1004u16 => Messages :: SetPingInterval (< SetPingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1400u16 => Messages :: ContinuousStart (< ContinuousStartStruct as DeserializePayload > :: deserialize (payload)) , 1213u16 => Messages :: ProcessorTemperature (< ProcessorTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1215u16 => Messages :: PingEnable (< PingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1100u16 => Messages :: GotoBootloader (< GotoBootloaderStruct as DeserializePayload > :: deserialize (payload)) , 1211u16 => Messages :: DistanceSimple (< DistanceSimpleStruct as DeserializePayload > :: deserialize (payload)) , 1000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout] 1 + use crate :: message :: MessageInfo ; use crate :: message :: PingMessage ; use crate :: message :: SerializePayload ; use crate :: message :: DeserializePayload ; use crate :: message :: DeserializeGenericMessage ; use crate :: device :: Common ; use crate :: device :: PingDevice ; use crate :: error :: PingError ; use crate :: message :: ProtocolMessage ; use std :: convert :: TryInto ; use tokio :: io :: { AsyncRead , AsyncWrite } ; # [cfg (feature = "serde")] use serde :: { Deserialize , Serialize } ; # [derive (Debug)] pub struct Device { pub common : Common , } impl PingDevice for Device { fn get_common (& self) -> & Common { & self . common } fn get_mut_common (& mut self) -> & mut Common { & mut self . common } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub struct PingProtocolHead { pub source_device_id : u8 , pub destiny_device_id : u8 , } # [derive (Debug , Clone , PartialEq)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] pub enum Messages { FirmwareVersion (FirmwareVersionStruct) , SetOssProfileConfiguration (SetOssProfileConfigurationStruct) , Range (RangeStruct) , PingInterval (PingIntervalStruct) , ContinuousStop (ContinuousStopStruct) , GainSetting (GainSettingStruct) , TransmitDuration (TransmitDurationStruct) , Voltage5 (Voltage5Struct) , DeviceId (DeviceIdStruct) , SetGainSetting (SetGainSettingStruct) , OssProfileConfiguration (OssProfileConfigurationStruct) , PcbTemperature (PcbTemperatureStruct) , SetModeAuto (SetModeAutoStruct) , ModeAuto (ModeAutoStruct) , GeneralInfo (GeneralInfoStruct) , SetSpeedOfSound (SetSpeedOfSoundStruct) , SpeedOfSound (SpeedOfSoundStruct) , Distance (DistanceStruct) , SetRange (SetRangeStruct) , Profile (ProfileStruct) , SetPingEnable (SetPingEnableStruct) , SetPingInterval (SetPingIntervalStruct) , ContinuousStart (ContinuousStartStruct) , ProcessorTemperature (ProcessorTemperatureStruct) , PingEnable (PingEnableStruct) , GotoBootloader (GotoBootloaderStruct) , DistanceSimple (DistanceSimpleStruct) , SetDeviceId (SetDeviceIdStruct) , } impl Messages { pub fn inner < T : 'static > (& self) -> Option < & T > { match self { Self :: FirmwareVersion (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetOssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Range (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStop (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: TransmitDuration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Voltage5 (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetGainSetting (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: OssProfileConfiguration (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PcbTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ModeAuto (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GeneralInfo (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetSpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SpeedOfSound (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Distance (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetRange (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: Profile (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetPingInterval (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ContinuousStart (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: ProcessorTemperature (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: PingEnable (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: GotoBootloader (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: DistanceSimple (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , Self :: SetDeviceId (inner_struct) => (inner_struct as & dyn std :: any :: Any) . downcast_ref :: < T > () , } } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Device information"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Device information"] pub struct FirmwareVersionStruct { # [doc = "Device type. 0: Unknown; 1: Echosounder"] # [cfg_attr (feature = "schemars" , schemars (description = "Device type. 0: Unknown; 1: Echosounder"))] pub device_type : u8 , # [doc = "Device model. 0: Unknown; 1: Ping1D"] # [cfg_attr (feature = "schemars" , schemars (description = "Device model. 0: Unknown; 1: Ping1D"))] pub device_model : u8 , # [doc = "Firmware version major number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version major number."))] pub firmware_version_major : u16 , # [doc = "Firmware version minor number."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware version minor number."))] pub firmware_version_minor : u16 , } impl SerializePayload for FirmwareVersionStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_type . to_le_bytes ()) ; buffer . extend_from_slice (& self . device_model . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer } } impl DeserializePayload for FirmwareVersionStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_type : payload [0usize] . into () , device_model : payload [1usize] , firmware_version_major : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for FirmwareVersionStruct { fn id () -> u16 { 1200u16 } fn name () -> & 'static str { "firmware_version" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the profile output configuration. (Open source firmware only)"] pub struct SetOssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for SetOssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetOssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for SetOssProfileConfigurationStruct { fn id () -> u16 { 1007u16 } fn name () -> & 'static str { "set_oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub struct RangeStruct { # [doc = "The beginning of the scan range in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan range in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan range."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range."))] pub scan_length : u32 , } impl SerializePayload for RangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for RangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for RangeStruct { fn id () -> u16 { 1204u16 } fn name () -> & 'static str { "range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct PingIntervalStruct { # [doc = "The minimum interval between acoustic measurements. The actual interval may be longer."] # [cfg_attr (feature = "schemars" , schemars (description = "The minimum interval between acoustic measurements. The actual interval may be longer."))] pub ping_interval : u16 , } impl SerializePayload for PingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PingIntervalStruct { fn id () -> u16 { 1206u16 } fn name () -> & 'static str { "ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to stop the continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to stop the continuous data stream of profile messages."] pub struct ContinuousStopStruct { # [doc = "The message id to stop streaming. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stop streaming. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStopStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStopStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStopStruct { fn id () -> u16 { 1401u16 } fn name () -> & 'static str { "continuous_stop" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current gain setting."] pub struct GainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for GainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for GainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for GainSettingStruct { fn id () -> u16 { 1207u16 } fn name () -> & 'static str { "gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The duration of the acoustic activation/transmission."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The duration of the acoustic activation/transmission."] pub struct TransmitDurationStruct { # [doc = "Acoustic pulse duration."] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic pulse duration."))] pub transmit_duration : u16 , } impl SerializePayload for TransmitDurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer } } impl DeserializePayload for TransmitDurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { transmit_duration : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for TransmitDurationStruct { fn id () -> u16 { 1208u16 } fn name () -> & 'static str { "transmit_duration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The 5V rail voltage."] pub struct Voltage5Struct { # [doc = "The 5V rail voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "The 5V rail voltage."))] pub voltage_5 : u16 , } impl SerializePayload for Voltage5Struct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer } } impl DeserializePayload for Voltage5Struct { fn deserialize (payload : & [u8]) -> Self { Self { voltage_5 : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for Voltage5Struct { fn id () -> u16 { 1202u16 } fn name () -> & 'static str { "voltage_5" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The device ID."] pub struct DeviceIdStruct { # [doc = "The device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "The device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for DeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for DeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for DeviceIdStruct { fn id () -> u16 { 1201u16 } fn name () -> & 'static str { "device_id" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the current gain setting."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the current gain setting."] pub struct SetGainSettingStruct { # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , } impl SerializePayload for SetGainSettingStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetGainSettingStruct { fn deserialize (payload : & [u8]) -> Self { Self { gain_setting : payload [0usize] . into () , } } } impl MessageInfo for SetGainSettingStruct { fn id () -> u16 { 1005u16 } fn name () -> & 'static str { "set_gain_setting" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Get the profile output configuration. (Open source firmware only)"))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Get the profile output configuration. (Open source firmware only)"] pub struct OssProfileConfigurationStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub number_of_points : u16 , # [doc = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"))] pub normalization_enabled : u8 , # [doc = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] # [cfg_attr (feature = "schemars" , schemars (description = "If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"))] pub enhance_enabled : u8 , } impl SerializePayload for OssProfileConfigurationStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . number_of_points . to_le_bytes ()) ; buffer . extend_from_slice (& self . normalization_enabled . to_le_bytes ()) ; buffer . extend_from_slice (& self . enhance_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for OssProfileConfigurationStruct { fn deserialize (payload : & [u8]) -> Self { Self { number_of_points : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , normalization_enabled : payload [2usize] . into () , enhance_enabled : payload [3usize] . into () , } } } impl MessageInfo for OssProfileConfigurationStruct { fn id () -> u16 { 1301u16 } fn name () -> & 'static str { "oss_profile_configuration" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the on-board thermistor."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the on-board thermistor."] pub struct PcbTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub pcb_temperature : u16 , } impl SerializePayload for PcbTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . pcb_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for PcbTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { pcb_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for PcbTemperatureStruct { fn id () -> u16 { 1214u16 } fn name () -> & 'static str { "pcb_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] pub struct SetModeAutoStruct { # [doc = "0: manual mode. 1: auto mode."] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode. 1: auto mode."))] pub mode_auto : u8 , } impl SerializePayload for SetModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for SetModeAutoStruct { fn id () -> u16 { 1003u16 } fn name () -> & 'static str { "set_mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub struct ModeAutoStruct { # [doc = "0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for ModeAutoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for ModeAutoStruct { fn deserialize (payload : & [u8]) -> Self { Self { mode_auto : payload [0usize] . into () , } } } impl MessageInfo for ModeAutoStruct { fn id () -> u16 { 1205u16 } fn name () -> & 'static str { "mode_auto" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "General information."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "General information."] pub struct GeneralInfoStruct { # [doc = "Firmware major version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware major version."))] pub firmware_version_major : u16 , # [doc = "Firmware minor version."] # [cfg_attr (feature = "schemars" , schemars (description = "Firmware minor version."))] pub firmware_version_minor : u16 , # [doc = "Device supply voltage."] # [cfg_attr (feature = "schemars" , schemars (description = "Device supply voltage."))] pub voltage_5 : u16 , # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u8 , # [doc = "The current operating mode of the device. 0: manual mode, 1: auto mode"] # [cfg_attr (feature = "schemars" , schemars (description = "The current operating mode of the device. 0: manual mode, 1: auto mode"))] pub mode_auto : u8 , } impl SerializePayload for GeneralInfoStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . firmware_version_major . to_le_bytes ()) ; buffer . extend_from_slice (& self . firmware_version_minor . to_le_bytes ()) ; buffer . extend_from_slice (& self . voltage_5 . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . mode_auto . to_le_bytes ()) ; buffer } } impl DeserializePayload for GeneralInfoStruct { fn deserialize (payload : & [u8]) -> Self { Self { firmware_version_major : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , firmware_version_minor : u16 :: from_le_bytes (payload [2usize .. 2usize + 2usize] . try_into () . expect ("Wrong slice length")) , voltage_5 : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_interval : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , gain_setting : payload [8usize] . into () , mode_auto : payload [9usize] . into () , } } } impl MessageInfo for GeneralInfoStruct { fn id () -> u16 { 1210u16 } fn name () -> & 'static str { "general_info" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the speed of sound used for distance calculations."] pub struct SetSpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SetSpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetSpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetSpeedOfSoundStruct { fn id () -> u16 { 1002u16 } fn name () -> & 'static str { "set_speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound used for distance calculations."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The speed of sound used for distance calculations."] pub struct SpeedOfSoundStruct { # [doc = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] # [cfg_attr (feature = "schemars" , schemars (description = "The speed of sound in the measurement medium. ~1,500,000 mm/s for water."))] pub speed_of_sound : u32 , } impl SerializePayload for SpeedOfSoundStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . speed_of_sound . to_le_bytes ()) ; buffer } } impl DeserializePayload for SpeedOfSoundStruct { fn deserialize (payload : & [u8]) -> Self { Self { speed_of_sound : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SpeedOfSoundStruct { fn id () -> u16 { 1203u16 } fn name () -> & 'static str { "speed_of_sound" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub struct DistanceStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , } impl SerializePayload for DistanceStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for DistanceStruct { fn id () -> u16 { 1212u16 } fn name () -> & 'static str { "distance" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the scan range for acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the scan range for acoustic measurements."] pub struct SetRangeStruct { # [doc = "Not documented"] # [cfg_attr (feature = "schemars" , schemars (description = "Not documented"))] pub scan_start : u32 , # [doc = "The length of the scan range. Minimum 1000."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan range. Minimum 1000."))] pub scan_length : u32 , } impl SerializePayload for SetRangeStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetRangeStruct { fn deserialize (payload : & [u8]) -> Self { Self { scan_start : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [4usize .. 4usize + 4usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetRangeStruct { fn id () -> u16 { 1001u16 } fn name () -> & 'static str { "set_range" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub struct ProfileStruct { # [doc = "The current return distance determined for the most recent acoustic measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "The current return distance determined for the most recent acoustic measurement."))] pub distance : u32 , # [doc = "Confidence in the most recent range measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the most recent range measurement."))] pub confidence : u16 , # [doc = "The acoustic pulse length during acoustic transmission/activation."] # [cfg_attr (feature = "schemars" , schemars (description = "The acoustic pulse length during acoustic transmission/activation."))] pub transmit_duration : u16 , # [doc = "The pulse/measurement count since boot."] # [cfg_attr (feature = "schemars" , schemars (description = "The pulse/measurement count since boot."))] pub ping_number : u32 , # [doc = "The beginning of the scan region in mm from the transducer."] # [cfg_attr (feature = "schemars" , schemars (description = "The beginning of the scan region in mm from the transducer."))] pub scan_start : u32 , # [doc = "The length of the scan region."] # [cfg_attr (feature = "schemars" , schemars (description = "The length of the scan region."))] pub scan_length : u32 , # [doc = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] # [cfg_attr (feature = "schemars" , schemars (description = "The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"))] pub gain_setting : u32 , # [doc = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."] # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data_length : u16 , # [cfg_attr (feature = "schemars" , schemars (description = "An array of return strength measurements taken at regular intervals across the scan region. The first element is the closest measurement to the sensor, and the last element is the farthest measurement in the scanned range."))] pub profile_data : Vec < u8 > , } impl SerializePayload for ProfileStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer . extend_from_slice (& self . transmit_duration . to_le_bytes ()) ; buffer . extend_from_slice (& self . ping_number . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_start . to_le_bytes ()) ; buffer . extend_from_slice (& self . scan_length . to_le_bytes ()) ; buffer . extend_from_slice (& self . gain_setting . to_le_bytes ()) ; buffer . extend_from_slice (& self . profile_data_length . to_le_bytes ()) ; for value in self . profile_data . iter () { buffer . extend_from_slice (& value . to_le_bytes ()) ; } buffer } } impl DeserializePayload for ProfileStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : u16 :: from_le_bytes (payload [4usize .. 4usize + 2usize] . try_into () . expect ("Wrong slice length")) , transmit_duration : u16 :: from_le_bytes (payload [6usize .. 6usize + 2usize] . try_into () . expect ("Wrong slice length")) , ping_number : u32 :: from_le_bytes (payload [8usize .. 8usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_start : u32 :: from_le_bytes (payload [12usize .. 12usize + 4usize] . try_into () . expect ("Wrong slice length")) , scan_length : u32 :: from_le_bytes (payload [16usize .. 16usize + 4usize] . try_into () . expect ("Wrong slice length")) , gain_setting : u32 :: from_le_bytes (payload [20usize .. 20usize + 4usize] . try_into () . expect ("Wrong slice length")) , profile_data_length : u16 :: from_le_bytes (payload [24usize .. 24usize + 2usize] . try_into () . expect ("Wrong slice length")) , profile_data : payload [24usize + 2usize .. payload . len ()] . to_vec () , } } } impl MessageInfo for ProfileStruct { fn id () -> u16 { 1300u16 } fn name () -> & 'static str { "profile" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Enable or disable acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Enable or disable acoustic measurements."] pub struct SetPingEnableStruct { # [doc = "0: Disable, 1: Enable."] # [cfg_attr (feature = "schemars" , schemars (description = "0: Disable, 1: Enable."))] pub ping_enabled : u8 , } impl SerializePayload for SetPingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for SetPingEnableStruct { fn id () -> u16 { 1006u16 } fn name () -> & 'static str { "set_ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The interval between acoustic measurements."] pub struct SetPingIntervalStruct { # [doc = "The interval between acoustic measurements."] # [cfg_attr (feature = "schemars" , schemars (description = "The interval between acoustic measurements."))] pub ping_interval : u16 , } impl SerializePayload for SetPingIntervalStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_interval . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetPingIntervalStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_interval : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for SetPingIntervalStruct { fn id () -> u16 { 1004u16 } fn name () -> & 'static str { "set_ping_interval" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Command to initiate continuous data stream of profile messages."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Command to initiate continuous data stream of profile messages."] pub struct ContinuousStartStruct { # [doc = "The message id to stream. 1300: profile"] # [cfg_attr (feature = "schemars" , schemars (description = "The message id to stream. 1300: profile"))] pub id : u16 , } impl SerializePayload for ContinuousStartStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . id . to_le_bytes ()) ; buffer } } impl DeserializePayload for ContinuousStartStruct { fn deserialize (payload : & [u8]) -> Self { Self { id : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ContinuousStartStruct { fn id () -> u16 { 1400u16 } fn name () -> & 'static str { "continuous_start" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Temperature of the device cpu."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Temperature of the device cpu."] pub struct ProcessorTemperatureStruct { # [doc = "The temperature in centi-degrees Centigrade (100 * degrees C)."] # [cfg_attr (feature = "schemars" , schemars (description = "The temperature in centi-degrees Centigrade (100 * degrees C)."))] pub processor_temperature : u16 , } impl SerializePayload for ProcessorTemperatureStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . processor_temperature . to_le_bytes ()) ; buffer } } impl DeserializePayload for ProcessorTemperatureStruct { fn deserialize (payload : & [u8]) -> Self { Self { processor_temperature : u16 :: from_le_bytes (payload [0usize .. 0usize + 2usize] . try_into () . expect ("Wrong slice length")) , } } } impl MessageInfo for ProcessorTemperatureStruct { fn id () -> u16 { 1213u16 } fn name () -> & 'static str { "processor_temperature" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Acoustic output enabled state."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Acoustic output enabled state."] pub struct PingEnableStruct { # [doc = "The state of the acoustic output. 0: disabled, 1:enabled"] # [cfg_attr (feature = "schemars" , schemars (description = "The state of the acoustic output. 0: disabled, 1:enabled"))] pub ping_enabled : u8 , } impl SerializePayload for PingEnableStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . ping_enabled . to_le_bytes ()) ; buffer } } impl DeserializePayload for PingEnableStruct { fn deserialize (payload : & [u8]) -> Self { Self { ping_enabled : payload [0usize] . into () , } } } impl MessageInfo for PingEnableStruct { fn id () -> u16 { 1215u16 } fn name () -> & 'static str { "ping_enable" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Send the device into the bootloader. This is useful for firmware updates."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Send the device into the bootloader. This is useful for firmware updates."] pub struct GotoBootloaderStruct { } impl SerializePayload for GotoBootloaderStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer } } impl DeserializePayload for GotoBootloaderStruct { fn deserialize (payload : & [u8]) -> Self { Self { } } } impl MessageInfo for GotoBootloaderStruct { fn id () -> u16 { 1100u16 } fn name () -> & 'static str { "goto_bootloader" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "The distance to target with confidence estimate."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "The distance to target with confidence estimate."] pub struct DistanceSimpleStruct { # [doc = "Distance to the target."] # [cfg_attr (feature = "schemars" , schemars (description = "Distance to the target."))] pub distance : u32 , # [doc = "Confidence in the distance measurement."] # [cfg_attr (feature = "schemars" , schemars (description = "Confidence in the distance measurement."))] pub confidence : u8 , } impl SerializePayload for DistanceSimpleStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . distance . to_le_bytes ()) ; buffer . extend_from_slice (& self . confidence . to_le_bytes ()) ; buffer } } impl DeserializePayload for DistanceSimpleStruct { fn deserialize (payload : & [u8]) -> Self { Self { distance : u32 :: from_le_bytes (payload [0usize .. 0usize + 4usize] . try_into () . expect ("Wrong slice length")) , confidence : payload [4usize] . into () , } } } impl MessageInfo for DistanceSimpleStruct { fn id () -> u16 { 1211u16 } fn name () -> & 'static str { "distance_simple" } } # [derive (Debug , Clone , PartialEq , Default)] # [cfg_attr (feature = "serde" , derive (Serialize , Deserialize))] # [cfg_attr (feature = "schemars" , derive (schemars :: JsonSchema))] # [cfg_attr (feature = "schemars" , schemars (description = "Set the device ID."))] # [cfg_attr (any (test , feature = "arbitrary") , derive (arbitrary :: Arbitrary))] # [doc = "Set the device ID."] pub struct SetDeviceIdStruct { # [doc = "Device ID (0-254). 255 is reserved for broadcast messages."] # [cfg_attr (feature = "schemars" , schemars (description = "Device ID (0-254). 255 is reserved for broadcast messages."))] pub device_id : u8 , } impl SerializePayload for SetDeviceIdStruct { fn serialize (& self) -> Vec < u8 > { let mut buffer : Vec < u8 > = Default :: default () ; buffer . extend_from_slice (& self . device_id . to_le_bytes ()) ; buffer } } impl DeserializePayload for SetDeviceIdStruct { fn deserialize (payload : & [u8]) -> Self { Self { device_id : payload [0usize] . into () , } } } impl MessageInfo for SetDeviceIdStruct { fn id () -> u16 { 1000u16 } fn name () -> & 'static str { "set_device_id" } } impl Device { pub fn new < T > (io : T) -> Self where T : AsyncRead + AsyncWrite + Unpin + Send + 'static , { Self { common : Common :: new (io) , } } # [doc = "Device information"] pub async fn firmware_version (& self) -> Result < FirmwareVersionStruct , PingError > { self . request () . await } # [doc = "Set the profile output configuration. (Open source firmware only)"] # [doc = "# Arguments"] # [doc = "* `number_of_points` - Not documented"] # [doc = "* `normalization_enabled` - If enabled, the profile data is scaled so that the maximum value aligns with the upper limit of 255. (0: Disabled, 1: Enabled)"] # [doc = "* `enhance_enabled` - If enabled, the profile data will be unevenly scaled to enhance peak values. (0: Disabled, 1: Enabled)"] pub async fn set_oss_profile_configuration (& self , number_of_points : u16 , normalization_enabled : u8 , enhance_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetOssProfileConfiguration (SetOssProfileConfigurationStruct { number_of_points , normalization_enabled , enhance_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetOssProfileConfigurationStruct :: id ()) . await } # [doc = "The scan range for acoustic measurements. Measurements returned by the device will lie in the range (scan_start, scan_start + scan_length)."] pub async fn range (& self) -> Result < RangeStruct , PingError > { self . request () . await } # [doc = "The interval between acoustic measurements."] pub async fn ping_interval (& self) -> Result < PingIntervalStruct , PingError > { self . request () . await } # [doc = "Command to stop the continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stop streaming. 1300: profile"] pub async fn continuous_stop (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStop (ContinuousStopStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The current gain setting."] pub async fn gain_setting (& self) -> Result < GainSettingStruct , PingError > { self . request () . await } # [doc = "The duration of the acoustic activation/transmission."] pub async fn transmit_duration (& self) -> Result < TransmitDurationStruct , PingError > { self . request () . await } # [doc = "The 5V rail voltage."] pub async fn voltage_5 (& self) -> Result < Voltage5Struct , PingError > { self . request () . await } # [doc = "The device ID."] pub async fn device_id (& self) -> Result < DeviceIdStruct , PingError > { self . request () . await } # [doc = "Set the current gain setting."] # [doc = "# Arguments"] # [doc = "* `gain_setting` - The current gain setting. 0: 0.6, 1: 1.8, 2: 5.5, 3: 12.9, 4: 30.2, 5: 66.1, 6: 144"] pub async fn set_gain_setting (& self , gain_setting : u8) -> Result < () , PingError > { let request = Messages :: SetGainSetting (SetGainSettingStruct { gain_setting , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetGainSettingStruct :: id ()) . await } # [doc = "Get the profile output configuration. (Open source firmware only)"] pub async fn oss_profile_configuration (& self) -> Result < OssProfileConfigurationStruct , PingError > { self . request () . await } # [doc = "Temperature of the on-board thermistor."] pub async fn pcb_temperature (& self) -> Result < PcbTemperatureStruct , PingError > { self . request () . await } # [doc = "Set automatic or manual mode. Manual mode allows for manual selection of the gain and scan range."] # [doc = "# Arguments"] # [doc = "* `mode_auto` - 0: manual mode. 1: auto mode."] pub async fn set_mode_auto (& self , mode_auto : u8) -> Result < () , PingError > { let request = Messages :: SetModeAuto (SetModeAutoStruct { mode_auto , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetModeAutoStruct :: id ()) . await } # [doc = "The current operating mode of the device. Manual mode allows for manual selection of the gain and scan range."] pub async fn mode_auto (& self) -> Result < ModeAutoStruct , PingError > { self . request () . await } # [doc = "General information."] pub async fn general_info (& self) -> Result < GeneralInfoStruct , PingError > { self . request () . await } # [doc = "Set the speed of sound used for distance calculations."] # [doc = "# Arguments"] # [doc = "* `speed_of_sound` \\[mm/s\\] - The speed of sound in the measurement medium. ~1,500,000 mm/s for water."] pub async fn set_speed_of_sound (& self , speed_of_sound : u32) -> Result < () , PingError > { let request = Messages :: SetSpeedOfSound (SetSpeedOfSoundStruct { speed_of_sound , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetSpeedOfSoundStruct :: id ()) . await } # [doc = "The speed of sound used for distance calculations."] pub async fn speed_of_sound (& self) -> Result < SpeedOfSoundStruct , PingError > { self . request () . await } # [doc = "The distance to target with confidence estimate. Relevant device parameters during the measurement are also provided."] pub async fn distance (& self) -> Result < DistanceStruct , PingError > { self . request () . await } # [doc = "Set the scan range for acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `scan_start` \\[mm\\] - Not documented"] # [doc = "* `scan_length` \\[mm\\] - The length of the scan range. Minimum 1000."] pub async fn set_range (& self , scan_start : u32 , scan_length : u32) -> Result < () , PingError > { let request = Messages :: SetRange (SetRangeStruct { scan_start , scan_length , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetRangeStruct :: id ()) . await } # [doc = "A profile produced from a single acoustic measurement. The data returned is an array of response strength at even intervals across the scan region. The scan region is defined as the region between <scan_start> and <scan_start + scan_length> millimeters away from the transducer. A distance measurement to the target is also provided."] pub async fn profile (& self) -> Result < ProfileStruct , PingError > { self . request () . await } # [doc = "Enable or disable acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_enabled` - 0: Disable, 1: Enable."] pub async fn set_ping_enable (& self , ping_enabled : u8) -> Result < () , PingError > { let request = Messages :: SetPingEnable (SetPingEnableStruct { ping_enabled , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingEnableStruct :: id ()) . await } # [doc = "The interval between acoustic measurements."] # [doc = "# Arguments"] # [doc = "* `ping_interval` \\[ms\\] - The interval between acoustic measurements."] pub async fn set_ping_interval (& self , ping_interval : u16) -> Result < () , PingError > { let request = Messages :: SetPingInterval (SetPingIntervalStruct { ping_interval , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetPingIntervalStruct :: id ()) . await } # [doc = "Command to initiate continuous data stream of profile messages."] # [doc = "# Arguments"] # [doc = "* `id` - The message id to stream. 1300: profile"] pub async fn continuous_start (& self , id : u16) -> Result < () , PingError > { let request = Messages :: ContinuousStart (ContinuousStartStruct { id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "Temperature of the device cpu."] pub async fn processor_temperature (& self) -> Result < ProcessorTemperatureStruct , PingError > { self . request () . await } # [doc = "Acoustic output enabled state."] pub async fn ping_enable (& self) -> Result < PingEnableStruct , PingError > { self . request () . await } # [doc = "Send the device into the bootloader. This is useful for firmware updates."] # [doc = "# Arguments"] pub async fn goto_bootloader (& self ,) -> Result < () , PingError > { let request = Messages :: GotoBootloader (GotoBootloaderStruct { }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; self . get_common () . send_message (package) . await ? ; Ok (()) } # [doc = "The distance to target with confidence estimate."] pub async fn distance_simple (& self) -> Result < DistanceSimpleStruct , PingError > { self . request () . await } # [doc = "Set the device ID."] # [doc = "# Arguments"] # [doc = "* `device_id` - Device ID (0-254). 255 is reserved for broadcast messages."] pub async fn set_device_id (& self , device_id : u8) -> Result < () , PingError > { let request = Messages :: SetDeviceId (SetDeviceIdStruct { device_id , }) ; let mut package = ProtocolMessage :: new () ; package . set_message (& request) ; let receiver = self . subscribe () ; self . get_common () . send_message (package) . await ? ; self . wait_for_ack (receiver , SetDeviceIdStruct :: id ()) . await } } impl PingMessage for Messages { fn message_name (& self) -> & 'static str { match self { Messages :: FirmwareVersion (..) => "firmware_version" , Messages :: SetOssProfileConfiguration (..) => "set_oss_profile_configuration" , Messages :: Range (..) => "range" , Messages :: PingInterval (..) => "ping_interval" , Messages :: ContinuousStop (..) => "continuous_stop" , Messages :: GainSetting (..) => "gain_setting" , Messages :: TransmitDuration (..) => "transmit_duration" , Messages :: Voltage5 (..) => "voltage_5" , Messages :: DeviceId (..) => "device_id" , Messages :: SetGainSetting (..) => "set_gain_setting" , Messages :: OssProfileConfiguration (..) => "oss_profile_configuration" , Messages :: PcbTemperature (..) => "pcb_temperature" , Messages :: SetModeAuto (..) => "set_mode_auto" , Messages :: ModeAuto (..) => "mode_auto" , Messages :: GeneralInfo (..) => "general_info" , Messages :: SetSpeedOfSound (..) => "set_speed_of_sound" , Messages :: SpeedOfSound (..) => "speed_of_sound" , Messages :: Distance (..) => "distance" , Messages :: SetRange (..) => "set_range" , Messages :: Profile (..) => "profile" , Messages :: SetPingEnable (..) => "set_ping_enable" , Messages :: SetPingInterval (..) => "set_ping_interval" , Messages :: ContinuousStart (..) => "continuous_start" , Messages :: ProcessorTemperature (..) => "processor_temperature" , Messages :: PingEnable (..) => "ping_enable" , Messages :: GotoBootloader (..) => "goto_bootloader" , Messages :: DistanceSimple (..) => "distance_simple" , Messages :: SetDeviceId (..) => "set_device_id" , } } fn message_id (& self) -> u16 { match self { Messages :: FirmwareVersion (..) => 1200u16 , Messages :: SetOssProfileConfiguration (..) => 1007u16 , Messages :: Range (..) => 1204u16 , Messages :: PingInterval (..) => 1206u16 , Messages :: ContinuousStop (..) => 1401u16 , Messages :: GainSetting (..) => 1207u16 , Messages :: TransmitDuration (..) => 1208u16 , Messages :: Voltage5 (..) => 1202u16 , Messages :: DeviceId (..) => 1201u16 , Messages :: SetGainSetting (..) => 1005u16 , Messages :: OssProfileConfiguration (..) => 1301u16 , Messages :: PcbTemperature (..) => 1214u16 , Messages :: SetModeAuto (..) => 1003u16 , Messages :: ModeAuto (..) => 1205u16 , Messages :: GeneralInfo (..) => 1210u16 , Messages :: SetSpeedOfSound (..) => 1002u16 , Messages :: SpeedOfSound (..) => 1203u16 , Messages :: Distance (..) => 1212u16 , Messages :: SetRange (..) => 1001u16 , Messages :: Profile (..) => 1300u16 , Messages :: SetPingEnable (..) => 1006u16 , Messages :: SetPingInterval (..) => 1004u16 , Messages :: ContinuousStart (..) => 1400u16 , Messages :: ProcessorTemperature (..) => 1213u16 , Messages :: PingEnable (..) => 1215u16 , Messages :: GotoBootloader (..) => 1100u16 , Messages :: DistanceSimple (..) => 1211u16 , Messages :: SetDeviceId (..) => 1000u16 , } } fn message_id_from_name (name : & str) -> Result < u16 , String > { match name { "firmware_version" => Ok (1200u16) , "set_oss_profile_configuration" => Ok (1007u16) , "range" => Ok (1204u16) , "ping_interval" => Ok (1206u16) , "continuous_stop" => Ok (1401u16) , "gain_setting" => Ok (1207u16) , "transmit_duration" => Ok (1208u16) , "voltage_5" => Ok (1202u16) , "device_id" => Ok (1201u16) , "set_gain_setting" => Ok (1005u16) , "oss_profile_configuration" => Ok (1301u16) , "pcb_temperature" => Ok (1214u16) , "set_mode_auto" => Ok (1003u16) , "mode_auto" => Ok (1205u16) , "general_info" => Ok (1210u16) , "set_speed_of_sound" => Ok (1002u16) , "speed_of_sound" => Ok (1203u16) , "distance" => Ok (1212u16) , "set_range" => Ok (1001u16) , "profile" => Ok (1300u16) , "set_ping_enable" => Ok (1006u16) , "set_ping_interval" => Ok (1004u16) , "continuous_start" => Ok (1400u16) , "processor_temperature" => Ok (1213u16) , "ping_enable" => Ok (1215u16) , "goto_bootloader" => Ok (1100u16) , "distance_simple" => Ok (1211u16) , "set_device_id" => Ok (1000u16) , _ => Err (format ! ("Failed to find message ID from name: {name}.")) , } } } impl SerializePayload for Messages { fn serialize (& self) -> Vec < u8 > { match self { Messages :: FirmwareVersion (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetOssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Range (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStop (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: TransmitDuration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Voltage5 (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DeviceId (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetGainSetting (content) => (content as & dyn SerializePayload) . serialize () , Messages :: OssProfileConfiguration (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PcbTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ModeAuto (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GeneralInfo (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetSpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SpeedOfSound (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Distance (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetRange (content) => (content as & dyn SerializePayload) . serialize () , Messages :: Profile (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetPingInterval (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ContinuousStart (content) => (content as & dyn SerializePayload) . serialize () , Messages :: ProcessorTemperature (content) => (content as & dyn SerializePayload) . serialize () , Messages :: PingEnable (content) => (content as & dyn SerializePayload) . serialize () , Messages :: GotoBootloader (content) => (content as & dyn SerializePayload) . serialize () , Messages :: DistanceSimple (content) => (content as & dyn SerializePayload) . serialize () , Messages :: SetDeviceId (content) => (content as & dyn SerializePayload) . serialize () , } } } impl DeserializeGenericMessage for Messages { fn deserialize (message_id : u16 , payload : & [u8]) -> Result < Self , & 'static str > { Ok (match message_id { 1200u16 => Messages :: FirmwareVersion (< FirmwareVersionStruct as DeserializePayload > :: deserialize (payload)) , 1007u16 => Messages :: SetOssProfileConfiguration (< SetOssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1204u16 => Messages :: Range (< RangeStruct as DeserializePayload > :: deserialize (payload)) , 1206u16 => Messages :: PingInterval (< PingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1401u16 => Messages :: ContinuousStop (< ContinuousStopStruct as DeserializePayload > :: deserialize (payload)) , 1207u16 => Messages :: GainSetting (< GainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1208u16 => Messages :: TransmitDuration (< TransmitDurationStruct as DeserializePayload > :: deserialize (payload)) , 1202u16 => Messages :: Voltage5 (< Voltage5Struct as DeserializePayload > :: deserialize (payload)) , 1201u16 => Messages :: DeviceId (< DeviceIdStruct as DeserializePayload > :: deserialize (payload)) , 1005u16 => Messages :: SetGainSetting (< SetGainSettingStruct as DeserializePayload > :: deserialize (payload)) , 1301u16 => Messages :: OssProfileConfiguration (< OssProfileConfigurationStruct as DeserializePayload > :: deserialize (payload)) , 1214u16 => Messages :: PcbTemperature (< PcbTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1003u16 => Messages :: SetModeAuto (< SetModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1205u16 => Messages :: ModeAuto (< ModeAutoStruct as DeserializePayload > :: deserialize (payload)) , 1210u16 => Messages :: GeneralInfo (< GeneralInfoStruct as DeserializePayload > :: deserialize (payload)) , 1002u16 => Messages :: SetSpeedOfSound (< SetSpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1203u16 => Messages :: SpeedOfSound (< SpeedOfSoundStruct as DeserializePayload > :: deserialize (payload)) , 1212u16 => Messages :: Distance (< DistanceStruct as DeserializePayload > :: deserialize (payload)) , 1001u16 => Messages :: SetRange (< SetRangeStruct as DeserializePayload > :: deserialize (payload)) , 1300u16 => Messages :: Profile (< ProfileStruct as DeserializePayload > :: deserialize (payload)) , 1006u16 => Messages :: SetPingEnable (< SetPingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1004u16 => Messages :: SetPingInterval (< SetPingIntervalStruct as DeserializePayload > :: deserialize (payload)) , 1400u16 => Messages :: ContinuousStart (< ContinuousStartStruct as DeserializePayload > :: deserialize (payload)) , 1213u16 => Messages :: ProcessorTemperature (< ProcessorTemperatureStruct as DeserializePayload > :: deserialize (payload)) , 1215u16 => Messages :: PingEnable (< PingEnableStruct as DeserializePayload > :: deserialize (payload)) , 1100u16 => Messages :: GotoBootloader (< GotoBootloaderStruct as DeserializePayload > :: deserialize (payload)) , 1211u16 => Messages :: DistanceSimple (< DistanceSimpleStruct as DeserializePayload > :: deserialize (payload)) , 1000u16 => Messages :: SetDeviceId (< SetDeviceIdStruct as DeserializePayload > :: deserialize (payload)) , _ => { return Err (& "Unknown message id") ; } }) } }
[INFO] [stdout]   |
[INFO] [stdout] help: you can use the fully-qualified path to avoid triggering this lint
[INFO] [stdout]   |
[WARN] too much data in the log, truncating it
