ascom_alpaca/api/
telescope.rs

1pub use super::camera_telescope_shared::GuideDirection;
2
3use super::Device;
4use super::time_repr::{Iso8601, TimeRepr};
5#[cfg(feature = "client")]
6use crate::api::macros::ConvertConvenienceProp;
7use crate::{ASCOMError, ASCOMResult};
8use macro_rules_attribute::apply;
9use num_enum::{IntoPrimitive, TryFromPrimitive};
10use serde::{Deserialize, Serialize};
11use serde_repr::{Deserialize_repr, Serialize_repr};
12use std::ops::RangeInclusive;
13use std::time::SystemTime;
14
15/// Telescope Specific Methods.
16#[apply(rpc_trait)]
17pub trait Telescope: Device + Send + Sync {
18    /// Returns the alignment mode of the mount (Alt/Az, Polar, German Polar).
19    #[http("alignmentmode", method = Get)]
20    async fn alignment_mode(&self) -> ASCOMResult<AlignmentMode> {
21        Err(ASCOMError::NOT_IMPLEMENTED)
22    }
23
24    /// The altitude above the local horizon of the mount's current position (degrees, positive up).
25    #[http("altitude", method = Get, device_state = Altitude)]
26    async fn altitude(&self) -> ASCOMResult<f64> {
27        Err(ASCOMError::NOT_IMPLEMENTED)
28    }
29
30    /// The area of the telescope's aperture, taking into account any obstructions (square meters).
31    #[http("aperturearea", method = Get)]
32    async fn aperture_area(&self) -> ASCOMResult<f64> {
33        Err(ASCOMError::NOT_IMPLEMENTED)
34    }
35
36    /// The telescope's effective aperture diameter (meters).
37    #[http("aperturediameter", method = Get)]
38    async fn aperture_diameter(&self) -> ASCOMResult<f64> {
39        Err(ASCOMError::NOT_IMPLEMENTED)
40    }
41
42    /// True if the mount is stopped in the Home position.
43    ///
44    /// Set only following a FindHome()  operation, and reset with any slew operation. This property must be False if the telescope does not support homing.
45    #[http("athome", method = Get, device_state = AtHome)]
46    async fn at_home(&self) -> ASCOMResult<bool>;
47
48    /// True if the telescope has been put into the parked state by the seee Park()  method.
49    ///
50    /// Set False by calling the Unpark() method.
51    #[http("atpark", method = Get, device_state = AtPark)]
52    async fn at_park(&self) -> ASCOMResult<bool>;
53
54    /// The azimuth at the local horizon of the mount's current position (degrees, North-referenced, positive East/clockwise).
55    #[http("azimuth", method = Get, device_state = Azimuth)]
56    async fn azimuth(&self) -> ASCOMResult<f64> {
57        Err(ASCOMError::NOT_IMPLEMENTED)
58    }
59
60    /// True if this telescope is capable of programmed finding its home position (FindHome()  method).
61    #[http("canfindhome", method = Get)]
62    async fn can_find_home(&self) -> ASCOMResult<bool> {
63        Ok(false)
64    }
65
66    /// True if this telescope is capable of programmed parking (Park() method).
67    #[http("canpark", method = Get)]
68    async fn can_park(&self) -> ASCOMResult<bool> {
69        Ok(false)
70    }
71
72    /// True if this telescope is capable of software-pulsed guiding (via the PulseGuide(GuideDirections, Int32) method).
73    #[http("canpulseguide", method = Get)]
74    async fn can_pulse_guide(&self) -> ASCOMResult<bool> {
75        Ok(false)
76    }
77
78    /// True if the DeclinationRate property can be changed to provide offset tracking in the declination axis.
79    #[http("cansetdeclinationrate", method = Get)]
80    async fn can_set_declination_rate(&self) -> ASCOMResult<bool> {
81        Ok(false)
82    }
83
84    /// True if the guide rate properties used for PulseGuide(GuideDirections, Int32) can ba adjusted.
85    #[http("cansetguiderates", method = Get)]
86    async fn can_set_guide_rates(&self) -> ASCOMResult<bool> {
87        Ok(false)
88    }
89
90    /// True if this telescope is capable of programmed setting of its park position (SetPark() method).
91    #[http("cansetpark", method = Get)]
92    async fn can_set_park(&self) -> ASCOMResult<bool> {
93        Ok(false)
94    }
95
96    /// True if the SideOfPier property can be set, meaning that the mount can be forced to flip.
97    #[http("cansetpierside", method = Get)]
98    async fn can_set_pier_side(&self) -> ASCOMResult<bool> {
99        Ok(false)
100    }
101
102    /// True if the RightAscensionRate property can be changed to provide offset tracking in the right ascension axis. .
103    #[http("cansetrightascensionrate", method = Get)]
104    async fn can_set_right_ascension_rate(&self) -> ASCOMResult<bool> {
105        Ok(false)
106    }
107
108    /// True if the Tracking property can be changed, turning telescope sidereal tracking on and off.
109    #[http("cansettracking", method = Get)]
110    async fn can_set_tracking(&self) -> ASCOMResult<bool> {
111        Ok(false)
112    }
113
114    /// True if this telescope is capable of programmed slewing (synchronous or asynchronous) to equatorial coordinates.
115    #[http("canslew", method = Get)]
116    async fn can_slew(&self) -> ASCOMResult<bool> {
117        Ok(false)
118    }
119
120    /// True if this telescope is capable of programmed slewing (synchronous or asynchronous) to local horizontal coordinates.
121    #[http("canslewaltaz", method = Get)]
122    async fn can_slew_alt_az(&self) -> ASCOMResult<bool> {
123        Ok(false)
124    }
125
126    /// True if this telescope is capable of programmed asynchronous slewing to local horizontal coordinates.
127    #[http("canslewaltazasync", method = Get)]
128    async fn can_slew_alt_az_async(&self) -> ASCOMResult<bool> {
129        Ok(false)
130    }
131
132    /// True if this telescope is capable of programmed asynchronous slewing to equatorial coordinates.
133    #[http("canslewasync", method = Get)]
134    async fn can_slew_async(&self) -> ASCOMResult<bool> {
135        Ok(false)
136    }
137
138    /// True if this telescope is capable of programmed synching to equatorial coordinates.
139    #[http("cansync", method = Get)]
140    async fn can_sync(&self) -> ASCOMResult<bool> {
141        Ok(false)
142    }
143
144    /// True if this telescope is capable of programmed synching to local horizontal coordinates.
145    #[http("cansyncaltaz", method = Get)]
146    async fn can_sync_alt_az(&self) -> ASCOMResult<bool> {
147        Ok(false)
148    }
149
150    /// True if this telescope is capable of programmed unparking (UnPark() method).
151    #[http("canunpark", method = Get)]
152    async fn can_unpark(&self) -> ASCOMResult<bool> {
153        Ok(false)
154    }
155
156    /// The declination (degrees) of the mount's current equatorial coordinates, in the coordinate system given by the EquatorialSystem property.
157    ///
158    /// Reading the property will raise an error if the value is unavailable.
159    #[http("declination", method = Get, device_state = Declination)]
160    async fn declination(&self) -> ASCOMResult<f64> {
161        Err(ASCOMError::NOT_IMPLEMENTED)
162    }
163
164    /// The declination tracking rate (arcseconds per SI second, default = 0.0).
165    ///
166    /// Please note that rightascensionrate units are arcseconds per sidereal second.
167    #[http("declinationrate", method = Get)]
168    async fn declination_rate(&self) -> ASCOMResult<f64>;
169
170    /// Sets the declination tracking rate (arcseconds per SI second).
171    ///
172    /// Please note that rightascensionrate units are arcseconds per sidereal second.
173    #[http("declinationrate", method = Put)]
174    async fn set_declination_rate(
175        &self,
176
177        #[http("DeclinationRate")] declination_rate: f64,
178    ) -> ASCOMResult<()> {
179        Err(ASCOMError::NOT_IMPLEMENTED)
180    }
181
182    /// True if the telescope or driver applies atmospheric refraction to coordinates.
183    #[http("doesrefraction", method = Get)]
184    async fn does_refraction(&self) -> ASCOMResult<bool> {
185        Err(ASCOMError::NOT_IMPLEMENTED)
186    }
187
188    /// Causes the rotator to move Position degrees relative to the current Position value.
189    #[http("doesrefraction", method = Put)]
190    async fn set_does_refraction(
191        &self,
192
193        #[http("DoesRefraction")] does_refraction: bool,
194    ) -> ASCOMResult<()> {
195        Err(ASCOMError::NOT_IMPLEMENTED)
196    }
197
198    /// Returns the current equatorial coordinate system used by this telescope (e.g. Topocentric or J2000).
199    #[http("equatorialsystem", method = Get)]
200    async fn equatorial_system(&self) -> ASCOMResult<EquatorialCoordinateType>;
201
202    /// The telescope's focal length in meters.
203    #[http("focallength", method = Get)]
204    async fn focal_length(&self) -> ASCOMResult<f64> {
205        Err(ASCOMError::NOT_IMPLEMENTED)
206    }
207
208    /// The current Declination movement rate offset for telescope guiding (degrees/sec).
209    #[http("guideratedeclination", method = Get)]
210    async fn guide_rate_declination(&self) -> ASCOMResult<f64> {
211        Err(ASCOMError::NOT_IMPLEMENTED)
212    }
213
214    /// Sets the current Declination movement rate offset for telescope guiding (degrees/sec).
215    #[http("guideratedeclination", method = Put)]
216    async fn set_guide_rate_declination(
217        &self,
218
219        #[http("GuideRateDeclination")] guide_rate_declination: f64,
220    ) -> ASCOMResult<()> {
221        Err(ASCOMError::NOT_IMPLEMENTED)
222    }
223
224    /// The current RightAscension movement rate offset for telescope guiding (degrees/sec).
225    #[http("guideraterightascension", method = Get)]
226    async fn guide_rate_right_ascension(&self) -> ASCOMResult<f64> {
227        Err(ASCOMError::NOT_IMPLEMENTED)
228    }
229
230    /// Sets the current RightAscension movement rate offset for telescope guiding (degrees/sec).
231    #[http("guideraterightascension", method = Put)]
232    async fn set_guide_rate_right_ascension(
233        &self,
234
235        #[http("GuideRateRightAscension")] guide_rate_right_ascension: f64,
236    ) -> ASCOMResult<()> {
237        Err(ASCOMError::NOT_IMPLEMENTED)
238    }
239
240    /// True if a PulseGuide(GuideDirections, Int32) command is in progress, False otherwise.
241    #[http("ispulseguiding", method = Get, device_state = IsPulseGuiding)]
242    async fn is_pulse_guiding(&self) -> ASCOMResult<bool> {
243        Err(ASCOMError::NOT_IMPLEMENTED)
244    }
245
246    /// The right ascension (hours) of the mount's current equatorial coordinates, in the coordinate system given by the EquatorialSystem property.
247    #[http("rightascension", method = Get, device_state = RightAscension)]
248    async fn right_ascension(&self) -> ASCOMResult<f64>;
249
250    /// The right ascension tracking rate (arcseconds per sidereal second, default = 0.0).
251    ///
252    /// Please note that the declinationrate units are arcseconds per SI second.
253    #[http("rightascensionrate", method = Get)]
254    async fn right_ascension_rate(&self) -> ASCOMResult<f64>;
255
256    /// Sets the right ascension tracking rate (arcseconds per sidereal second).
257    ///
258    /// Please note that the declinationrate units are arcseconds per SI second.
259    #[http("rightascensionrate", method = Put)]
260    async fn set_right_ascension_rate(
261        &self,
262
263        #[http("RightAscensionRate")] right_ascension_rate: f64,
264    ) -> ASCOMResult<()> {
265        Err(ASCOMError::NOT_IMPLEMENTED)
266    }
267
268    /// Indicates the pointing state of the mount.
269    #[http("sideofpier", method = Get, device_state = SideOfPier)]
270    async fn side_of_pier(&self) -> ASCOMResult<PierSide> {
271        Err(ASCOMError::NOT_IMPLEMENTED)
272    }
273
274    /// Sets the pointing state of the mount.
275    #[http("sideofpier", method = Put)]
276    async fn set_side_of_pier(
277        &self,
278        #[http("SideOfPier")] side_of_pier: PierSide,
279    ) -> ASCOMResult<()> {
280        Err(ASCOMError::NOT_IMPLEMENTED)
281    }
282
283    /// The local apparent sidereal time from the telescope's internal clock (hours, sidereal).
284    #[http("siderealtime", method = Get)]
285    async fn sidereal_time(&self) -> ASCOMResult<f64>;
286
287    /// The elevation above mean sea level (meters) of the site at which the telescope is located.
288    #[http("siteelevation", method = Get)]
289    async fn site_elevation(&self) -> ASCOMResult<f64> {
290        Err(ASCOMError::NOT_IMPLEMENTED)
291    }
292
293    /// Sets the elevation above mean sea level (metres) of the site at which the telescope is located.
294    #[http("siteelevation", method = Put)]
295    async fn set_site_elevation(
296        &self,
297
298        #[http("SiteElevation")] site_elevation: f64,
299    ) -> ASCOMResult<()> {
300        Err(ASCOMError::NOT_IMPLEMENTED)
301    }
302
303    /// The geodetic latitude (degrees, positive North, WGS84) of the site at which the telescope is located.
304    #[http("sitelatitude", method = Get)]
305    async fn site_latitude(&self) -> ASCOMResult<f64> {
306        Err(ASCOMError::NOT_IMPLEMENTED)
307    }
308
309    /// Sets the observing site's latitude (degrees).
310    #[http("sitelatitude", method = Put)]
311    async fn set_site_latitude(
312        &self,
313        #[http("SiteLatitude")] site_latitude: f64,
314    ) -> ASCOMResult<()> {
315        Err(ASCOMError::NOT_IMPLEMENTED)
316    }
317
318    /// The longitude (degrees, positive East, WGS84) of the site at which the telescope is located.
319    #[http("sitelongitude", method = Get)]
320    async fn site_longitude(&self) -> ASCOMResult<f64> {
321        Err(ASCOMError::NOT_IMPLEMENTED)
322    }
323
324    /// Sets the observing site's longitude (degrees, positive East, WGS84).
325    #[http("sitelongitude", method = Put)]
326    async fn set_site_longitude(
327        &self,
328
329        #[http("SiteLongitude")] site_longitude: f64,
330    ) -> ASCOMResult<()> {
331        Err(ASCOMError::NOT_IMPLEMENTED)
332    }
333
334    /// True if telescope is currently moving in response to one of the Slew methods or the MoveAxis(TelescopeAxes, Double) method, False at all other times.
335    #[http("slewing", method = Get, device_state = Slewing)]
336    async fn slewing(&self) -> ASCOMResult<bool> {
337        Err(ASCOMError::NOT_IMPLEMENTED)
338    }
339
340    /// Returns the post-slew settling time (sec.).
341    #[http("slewsettletime", method = Get)]
342    async fn slew_settle_time(&self) -> ASCOMResult<i32> {
343        Err(ASCOMError::NOT_IMPLEMENTED)
344    }
345
346    /// Sets the  post-slew settling time (integer sec.).
347    #[http("slewsettletime", method = Put)]
348    async fn set_slew_settle_time(
349        &self,
350
351        #[http("SlewSettleTime")] slew_settle_time: i32,
352    ) -> ASCOMResult<()> {
353        Err(ASCOMError::NOT_IMPLEMENTED)
354    }
355
356    /// The declination (degrees, positive North) for the target of an equatorial slew or sync operation.
357    #[http("targetdeclination", method = Get)]
358    async fn target_declination(&self) -> ASCOMResult<f64> {
359        Err(ASCOMError::NOT_IMPLEMENTED)
360    }
361
362    /// Sets the declination (degrees, positive North) for the target of an equatorial slew or sync operation.
363    #[http("targetdeclination", method = Put)]
364    async fn set_target_declination(
365        &self,
366
367        #[http("TargetDeclination")] target_declination: f64,
368    ) -> ASCOMResult<()> {
369        Err(ASCOMError::NOT_IMPLEMENTED)
370    }
371
372    /// The right ascension (hours) for the target of an equatorial slew or sync operation.
373    #[http("targetrightascension", method = Get)]
374    async fn target_right_ascension(&self) -> ASCOMResult<f64> {
375        Err(ASCOMError::NOT_IMPLEMENTED)
376    }
377
378    /// Sets the right ascension (hours) for the target of an equatorial slew or sync operation.
379    #[http("targetrightascension", method = Put)]
380    async fn set_target_right_ascension(
381        &self,
382
383        #[http("TargetRightAscension")] target_right_ascension: f64,
384    ) -> ASCOMResult<()> {
385        Err(ASCOMError::NOT_IMPLEMENTED)
386    }
387
388    /// Returns the state of the telescope's sidereal tracking drive.
389    #[http("tracking", method = Get, device_state = Tracking)]
390    async fn tracking(&self) -> ASCOMResult<bool>;
391
392    /// Sets the state of the telescope's sidereal tracking drive.
393    #[http("tracking", method = Put)]
394    async fn set_tracking(&self, #[http("Tracking")] tracking: bool) -> ASCOMResult<()> {
395        Err(ASCOMError::NOT_IMPLEMENTED)
396    }
397
398    /// The current tracking rate of the telescope's sidereal drive.
399    #[http("trackingrate", method = Get)]
400    async fn tracking_rate(&self) -> ASCOMResult<DriveRate>;
401
402    /// Sets the tracking rate of the telescope's sidereal drive.
403    #[http("trackingrate", method = Put)]
404    async fn set_tracking_rate(
405        &self,
406
407        #[http("TrackingRate")] tracking_rate: DriveRate,
408    ) -> ASCOMResult<()> {
409        Err(ASCOMError::NOT_IMPLEMENTED)
410    }
411
412    /// Returns an array of supported DriveRates values that describe the permissible values of the TrackingRate property for this telescope type.
413    #[http("trackingrates", method = Get)]
414    async fn tracking_rates(&self) -> ASCOMResult<Vec<DriveRate>> {
415        Err(ASCOMError::NOT_IMPLEMENTED)
416    }
417
418    /// Returns the UTC date/time of the telescope's internal clock.
419    #[http("utcdate", method = Get, via = TimeRepr<Iso8601>)]
420    async fn utc_date(&self) -> ASCOMResult<SystemTime>;
421
422    /// Sets the UTC date/time of the telescope's internal clock.
423    #[http("utcdate", method = Put)]
424    async fn set_utc_date(
425        &self,
426
427        #[http("UTCDate", via = TimeRepr<Iso8601>)] utc_date: SystemTime,
428    ) -> ASCOMResult<()> {
429        Err(ASCOMError::NOT_IMPLEMENTED)
430    }
431
432    /// Immediately Stops a slew in progress.
433    #[http("abortslew", method = Put)]
434    async fn abort_slew(&self) -> ASCOMResult<()> {
435        Err(ASCOMError::NOT_IMPLEMENTED)
436    }
437
438    /// The rates at which the telescope may be moved about the specified axis by the MoveAxis(TelescopeAxes, Double) method.
439    #[http("axisrates", method = Get, via = AxisRates)]
440    async fn axis_rates(
441        &self,
442        #[http("Axis")] axis: TelescopeAxis,
443    ) -> ASCOMResult<Vec<RangeInclusive<f64>>>;
444
445    /// True if this telescope can move the requested axis.
446    #[http("canmoveaxis", method = Get)]
447    async fn can_move_axis(&self, #[http("Axis")] axis: TelescopeAxis) -> ASCOMResult<bool> {
448        Ok(false)
449    }
450
451    /// Predicts the pointing state that a German equatorial mount will be in if it slews to the given coordinates.
452    #[http("destinationsideofpier", method = Get)]
453    async fn destination_side_of_pier(
454        &self,
455
456        #[http("RightAscension")] right_ascension: f64,
457
458        #[http("Declination")] declination: f64,
459    ) -> ASCOMResult<PierSide> {
460        Err(ASCOMError::NOT_IMPLEMENTED)
461    }
462
463    /// Locates the telescope's "home" position (synchronous).
464    #[http("findhome", method = Put)]
465    async fn find_home(&self) -> ASCOMResult<()> {
466        Err(ASCOMError::NOT_IMPLEMENTED)
467    }
468
469    /// Move the telescope in one axis at the given rate.
470    #[http("moveaxis", method = Put)]
471    async fn move_axis(
472        &self,
473
474        #[http("Axis")] axis: TelescopeAxis,
475
476        #[http("Rate")] rate: f64,
477    ) -> ASCOMResult<()> {
478        Err(ASCOMError::NOT_IMPLEMENTED)
479    }
480
481    /// Move the telescope to its park position, stop all motion (or restrict to a small safe range), and set AtPark to True. ).
482    #[http("park", method = Put)]
483    async fn park(&self) -> ASCOMResult<()> {
484        Err(ASCOMError::NOT_IMPLEMENTED)
485    }
486
487    /// Moves the scope in the given direction for the given interval or time at the rate given by the corresponding guide rate property.
488    #[http("pulseguide", method = Put)]
489    async fn pulse_guide(
490        &self,
491
492        #[http("Direction")] direction: GuideDirection,
493
494        #[http("Duration")] duration: i32,
495    ) -> ASCOMResult<()> {
496        Err(ASCOMError::NOT_IMPLEMENTED)
497    }
498
499    /// Sets the telescope's park position to be its current position.
500    #[http("setpark", method = Put)]
501    async fn set_park(&self) -> ASCOMResult<()> {
502        Err(ASCOMError::NOT_IMPLEMENTED)
503    }
504
505    /// Move the telescope to the given local horizontal coordinates, return when slew is complete.
506    #[http("slewtoaltaz", method = Put)]
507    async fn slew_to_alt_az(
508        &self,
509
510        #[http("Azimuth")] azimuth: f64,
511
512        #[http("Altitude")] altitude: f64,
513    ) -> ASCOMResult<()> {
514        Err(ASCOMError::NOT_IMPLEMENTED)
515    }
516
517    /// Move the telescope to the given local horizontal coordinates, return immediately after the slew starts.
518    ///
519    /// The client can poll the Slewing method to determine when the mount reaches the intended coordinates.
520    #[http("slewtoaltazasync", method = Put)]
521    async fn slew_to_alt_az_async(
522        &self,
523
524        #[http("Azimuth")] azimuth: f64,
525
526        #[http("Altitude")] altitude: f64,
527    ) -> ASCOMResult<()> {
528        Err(ASCOMError::NOT_IMPLEMENTED)
529    }
530
531    /// Move the telescope to the given equatorial coordinates, return when slew is complete.
532    #[http("slewtocoordinates", method = Put)]
533    async fn slew_to_coordinates(
534        &self,
535
536        #[http("RightAscension")] right_ascension: f64,
537
538        #[http("Declination")] declination: f64,
539    ) -> ASCOMResult<()> {
540        Err(ASCOMError::NOT_IMPLEMENTED)
541    }
542
543    /// Move the telescope to the given equatorial coordinates, return immediatley after the slew starts.
544    ///
545    /// The client can poll the Slewing method to determine when the mount reaches the intended coordinates.
546    #[http("slewtocoordinatesasync", method = Put)]
547    async fn slew_to_coordinates_async(
548        &self,
549
550        #[http("RightAscension")] right_ascension: f64,
551
552        #[http("Declination")] declination: f64,
553    ) -> ASCOMResult<()> {
554        Err(ASCOMError::NOT_IMPLEMENTED)
555    }
556
557    /// **This method is deprecated in favour of [`slew_to_target_async`](Self::slew_to_target_async).**
558    ///
559    /// Move the telescope to the TargetRightAscension and TargetDeclination equatorial coordinates, return when slew is complete.
560    #[http("slewtotarget", method = Put)]
561    async fn slew_to_target(&self) -> ASCOMResult<()> {
562        Err(ASCOMError::NOT_IMPLEMENTED)
563    }
564
565    /// Move the telescope to the TargetRightAscension and TargetDeclination equatorial coordinates, return immediatley after the slew starts.
566    ///
567    /// The client can poll the Slewing method to determine when the mount reaches the intended coordinates.
568    #[http("slewtotargetasync", method = Put)]
569    async fn slew_to_target_async(&self) -> ASCOMResult<()> {
570        Err(ASCOMError::NOT_IMPLEMENTED)
571    }
572
573    /// Matches the scope's local horizontal coordinates to the given local horizontal coordinates.
574    #[http("synctoaltaz", method = Put)]
575    async fn sync_to_alt_az(
576        &self,
577
578        #[http("Azimuth")] azimuth: f64,
579
580        #[http("Altitude")] altitude: f64,
581    ) -> ASCOMResult<()> {
582        Err(ASCOMError::NOT_IMPLEMENTED)
583    }
584
585    /// Matches the scope's equatorial coordinates to the given equatorial coordinates.
586    #[http("synctocoordinates", method = Put)]
587    async fn sync_to_coordinates(
588        &self,
589
590        #[http("RightAscension")] right_ascension: f64,
591
592        #[http("Declination")] declination: f64,
593    ) -> ASCOMResult<()> {
594        Err(ASCOMError::NOT_IMPLEMENTED)
595    }
596
597    /// Matches the scope's equatorial coordinates to the TargetRightAscension and TargetDeclination equatorial coordinates.
598    #[http("synctotarget", method = Put)]
599    async fn sync_to_target(&self) -> ASCOMResult<()> {
600        Err(ASCOMError::NOT_IMPLEMENTED)
601    }
602
603    /// Takes telescope out of the Parked state.
604    #[http("unpark", method = Put)]
605    async fn unpark(&self) -> ASCOMResult<()> {
606        Err(ASCOMError::NOT_IMPLEMENTED)
607    }
608
609    /// This method returns the version of the ASCOM device interface contract to which this device complies.
610    ///
611    /// Only one interface version is current at a moment in time and all new devices should be built to the latest interface version. Applications can choose which device interface versions they support and it is in their interest to support  previous versions as well as the current version to ensure thay can use the largest number of devices.
612    #[http("interfaceversion", method = Get)]
613    async fn interface_version(&self) -> ASCOMResult<i32> {
614        Ok(4_i32)
615    }
616}
617
618/// The geodetic coordinates of the site at which the telescope is located.
619#[cfg(feature = "client")]
620#[derive(Debug, Clone, Copy, PartialEq)]
621pub struct SiteCoords {
622    /// Latitude (degrees, positive North, WGS84).
623    pub latitude: f64,
624    /// Longitude (degrees, positive East, WGS84).
625    pub longitude: f64,
626    /// Elevation above mean sea level (meters).
627    pub elevation: f64,
628}
629
630#[cfg(feature = "client")]
631impl ConvertConvenienceProp for SiteCoords {
632    type Inner = f64;
633    type Arr = [f64; 3];
634
635    fn from_arr([latitude, longitude, elevation]: Self::Arr) -> Self {
636        Self {
637            latitude,
638            longitude,
639            elevation,
640        }
641    }
642
643    fn into_arr(self) -> Self::Arr {
644        [self.latitude, self.longitude, self.elevation]
645    }
646}
647
648/// A struct for convenience properties that apply to both the right ascension and declination coordinates.
649#[cfg(feature = "client")]
650#[derive(Debug, Clone, Copy, PartialEq)]
651pub struct RaDec {
652    /// Value along the right ascension axis.
653    pub right_ascension: f64,
654    /// Value along the declination axis.
655    pub declination: f64,
656}
657
658#[cfg(feature = "client")]
659impl ConvertConvenienceProp for RaDec {
660    type Inner = f64;
661    type Arr = [f64; 2];
662
663    fn from_arr([right_ascension, declination]: Self::Arr) -> Self {
664        Self {
665            right_ascension,
666            declination,
667        }
668    }
669
670    fn into_arr(self) -> Self::Arr {
671        [self.right_ascension, self.declination]
672    }
673}
674
675convenience_props!(Telescope {
676    /// The current right ascension and declination movement rate offsets for telescope guiding (degrees/sec).
677    #[
678        /// Sets the right ascension and declination movement rate offsets for telescope guiding (degrees/sec).
679        set
680    ]
681    guide_rates_ra_dec(guide_rate_right_ascension, guide_rate_declination): RaDec,
682
683    /// The right ascension (hours) and declination (degrees) of the mount's current equatorial coordinates, in the coordinate system given by the EquatorialSystem property.
684    ra_dec(right_ascension, declination): RaDec,
685
686    /// The right ascension and declination tracking rates (arcseconds per sidereal second, default = 0.0).
687    #[
688        /// Set the right ascension and declination tracking rates (arcseconds per sidereal second).
689        set
690    ]
691    ra_dec_rates(right_ascension_rate, declination_rate): RaDec,
692
693    /// The altitude and azimuth (degrees) of the mount's current position at the local horizon.
694    alt_az(altitude, azimuth): RaDec,
695
696    /// The geodetic coordinates of the site at which the telescope is located.
697    #[
698        /// Set the geodetic coordinates of the site at which the telescope is located.
699        set
700    ]
701    site_coords(site_latitude, site_longitude, site_elevation): SiteCoords,
702
703    /// The right ascension (hours) and declination (degrees, positive North) for the target of an equatorial slew or sync operation.
704    #[
705        /// Set the right ascension (hours) and declination (degrees) for the target of an equatorial slew or sync operation.
706        set
707    ]
708    target_ra_dec(target_right_ascension, target_declination): RaDec,
709});
710
711/// The alignment mode (geometry) of the mount.
712#[derive(
713    Debug,
714    PartialEq,
715    Eq,
716    Clone,
717    Copy,
718    Serialize_repr,
719    Deserialize_repr,
720    TryFromPrimitive,
721    IntoPrimitive,
722)]
723#[repr(i32)]
724pub enum AlignmentMode {
725    /// Altitude-Azimuth type mount.
726    AltAz = 0,
727
728    /// Polar (equatorial) mount other than German equatorial.
729    Polar = 1,
730
731    /// German equatorial type mount.
732    GermanPolar = 2,
733}
734
735/// The equatorial coordinate system used by the mount.
736#[derive(
737    Debug,
738    PartialEq,
739    Eq,
740    Clone,
741    Copy,
742    Serialize_repr,
743    Deserialize_repr,
744    TryFromPrimitive,
745    IntoPrimitive,
746)]
747#[repr(i32)]
748pub enum EquatorialCoordinateType {
749    /// Custom or unknown equinox and/or reference frame.
750    Other = 0,
751
752    /// Topocentric coordinates.
753    Topocentric = 1,
754
755    /// J2000 equator/equinox.
756    J2000 = 2,
757
758    /// J2050 equator/equinox.
759    J2050 = 3,
760
761    /// B1950 equinox, FK4 reference frame.
762    B1950 = 4,
763}
764
765/// Returned side of pier.
766#[derive(
767    Debug,
768    PartialEq,
769    Eq,
770    Clone,
771    Copy,
772    Serialize_repr,
773    Deserialize_repr,
774    TryFromPrimitive,
775    IntoPrimitive,
776)]
777#[repr(i32)]
778pub enum PierSide {
779    /// Normal pointing state - Mount on the East side of pier (looking West).
780    East = 0,
781
782    /// Through the pole pointing state - Mount on the West side of pier (looking East).
783    West = 1,
784
785    /// Unknown or indeterminate.
786    Unknown = -1,
787}
788
789/// Integer value corresponding to one of the standard drive rates.
790#[derive(
791    Debug,
792    PartialEq,
793    Eq,
794    Clone,
795    Copy,
796    Serialize_repr,
797    Deserialize_repr,
798    TryFromPrimitive,
799    IntoPrimitive,
800)]
801#[repr(i32)]
802pub enum DriveRate {
803    /// Sidereal tracking rate (15.041 arcseconds per second).
804    Sidereal = 0,
805
806    /// Lunar tracking rate (14.685 arcseconds per second).
807    Lunar = 1,
808
809    /// Solar tracking rate (15.0 arcseconds per second).
810    Solar = 2,
811
812    /// King tracking rate (15.0369 arcseconds per second).
813    King = 3,
814}
815
816/// Axis rate object.
817#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
818#[serde(rename_all = "PascalCase")]
819struct AxisRate {
820    /// The minimum rate (degrees per second).
821    ///
822    /// This must always be a positive number. It indicates the maximum rate in either direction about the axis.
823    pub minimum: f64,
824
825    /// The maximum rate (degrees per second).
826    ///
827    /// This must always be a positive number. It indicates the maximum rate in either direction about the axis.
828    pub maximum: f64,
829}
830
831#[derive(Serialize, Deserialize)]
832#[serde(transparent)]
833pub(super) struct AxisRates(Vec<AxisRate>);
834
835impl From<AxisRates> for Vec<RangeInclusive<f64>> {
836    fn from(axis_rates: AxisRates) -> Self {
837        axis_rates
838            .0
839            .into_iter()
840            .map(|axis_rate| axis_rate.minimum..=axis_rate.maximum)
841            .collect()
842    }
843}
844
845impl From<Vec<RangeInclusive<f64>>> for AxisRates {
846    fn from(ranges: Vec<RangeInclusive<f64>>) -> Self {
847        Self(
848            ranges
849                .into_iter()
850                .map(|range| {
851                    let (minimum, maximum) = range.into_inner();
852                    AxisRate { minimum, maximum }
853                })
854                .collect(),
855        )
856    }
857}
858
859/// The axis about which rate information is desired.
860#[derive(
861    Debug,
862    PartialEq,
863    Eq,
864    Clone,
865    Copy,
866    Serialize_repr,
867    Deserialize_repr,
868    TryFromPrimitive,
869    IntoPrimitive,
870)]
871#[repr(i32)]
872pub enum TelescopeAxis {
873    /// Primary axis (e.g., Right Ascension or Azimuth).
874    Primary = 0,
875
876    /// Secondary axis (e.g., Declination or Altitude).
877    Secondary = 1,
878
879    /// Tertiary axis (e.g. imager rotator/de-rotator).
880    Tertiary = 2,
881}