use crate::coordinates::{EquatorialPosition, HorizontalPosition, TrackingRates};
use crate::error::MountResult;
use crate::protocol::{Direction, MountMode, SlewRate, TrackingRate};
#[derive(Debug, Clone)]
pub struct MountStatus {
pub is_tracking: bool,
pub is_slewing: bool,
pub mount_mode: MountMode,
pub tracking_rate: TrackingRate,
pub is_parked: bool,
pub is_connected: bool,
pub slew_rate: SlewRate,
pub guide_rate: f64,
pub pier_side: String,
}
impl Default for MountStatus {
fn default() -> Self {
Self {
is_tracking: false,
is_slewing: false,
mount_mode: MountMode::default(),
tracking_rate: TrackingRate::default(),
is_parked: true,
is_connected: false,
slew_rate: SlewRate::default(),
guide_rate: 0.5,
pier_side: "Unknown".to_string(),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct SiteLocation {
pub latitude: f64,
pub longitude: f64,
pub altitude: f64,
}
impl Default for SiteLocation {
fn default() -> Self {
Self {
latitude: 0.0,
longitude: 0.0,
altitude: 0.0,
}
}
}
impl SiteLocation {
pub fn new(latitude: f64, longitude: f64, altitude: f64) -> Self {
Self {
latitude,
longitude,
altitude,
}
}
}
pub trait Mount {
fn connect(&mut self) -> MountResult<()>;
fn disconnect(&mut self) -> MountResult<()>;
fn is_connected(&self) -> bool;
fn get_position(&self) -> MountResult<EquatorialPosition>;
fn get_altaz(&self) -> MountResult<HorizontalPosition>;
fn goto_equatorial(&mut self, position: EquatorialPosition) -> MountResult<()>;
fn goto_altaz(&mut self, position: HorizontalPosition) -> MountResult<()>;
fn is_slewing(&self) -> MountResult<bool>;
fn abort_slew(&mut self) -> MountResult<()>;
fn move_axis(&mut self, direction: Direction) -> MountResult<()>;
fn stop_axis(&mut self, direction: Direction) -> MountResult<()>;
fn stop_all(&mut self) -> MountResult<()>;
fn set_slew_rate(&mut self, rate: SlewRate) -> MountResult<()>;
fn set_tracking(&mut self, rate: TrackingRate) -> MountResult<()>;
fn tracking_on(&mut self) -> MountResult<()>;
fn tracking_off(&mut self) -> MountResult<()>;
fn is_tracking(&self) -> MountResult<bool>;
fn set_custom_tracking_rates(&mut self, rates: TrackingRates) -> MountResult<()>;
fn set_guide_rate(&mut self, rate: f64) -> MountResult<()>;
fn get_guide_rate(&self) -> MountResult<f64>;
fn guide_pulse(&mut self, direction: Direction, duration_ms: u32) -> MountResult<()>;
fn set_altaz_mode(&mut self) -> MountResult<()>;
fn set_polar_mode(&mut self) -> MountResult<()>;
fn get_mount_mode(&self) -> MountResult<MountMode>;
fn go_home(&mut self) -> MountResult<()>;
fn park(&mut self) -> MountResult<()>;
fn unpark(&mut self) -> MountResult<()>;
fn is_parked(&self) -> MountResult<bool>;
fn sync(&mut self, position: EquatorialPosition) -> MountResult<()>;
fn set_site_location(&mut self, location: SiteLocation) -> MountResult<()>;
fn get_site_location(&self) -> MountResult<SiteLocation>;
fn get_status(&self) -> MountResult<MountStatus>;
fn get_firmware_version(&self) -> MountResult<String>;
fn get_model(&self) -> MountResult<String>;
fn send_raw_command(&mut self, command: &str) -> MountResult<String>;
}
pub trait SimulatedMount: Mount {
fn advance_time(&mut self, duration: std::time::Duration);
fn set_time_multiplier(&mut self, multiplier: f64);
fn get_simulation_time(&self) -> chrono::DateTime<chrono::Utc>;
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_mount_status_default() {
let status = MountStatus::default();
assert!(!status.is_tracking);
assert!(!status.is_slewing);
assert!(status.is_parked);
assert!(!status.is_connected);
assert_eq!(status.mount_mode, MountMode::Equatorial);
}
#[test]
fn test_site_location() {
let loc = SiteLocation::new(34.0522, -118.2437, 71.0);
assert!((loc.latitude - 34.0522).abs() < 0.0001);
assert!((loc.longitude - (-118.2437)).abs() < 0.0001);
assert!((loc.altitude - 71.0).abs() < 0.0001);
}
#[test]
fn test_site_location_default() {
let loc = SiteLocation::default();
assert_eq!(loc.latitude, 0.0);
assert_eq!(loc.longitude, 0.0);
assert_eq!(loc.altitude, 0.0);
}
}