//tabs=4 // -------------------------------------------------------------------------------- // TODO fill in this information for your driver, then remove this line! // // ASCOM Telescope driver for MeadeAutostar497 // // Description: Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam // nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam // erat, sed diam voluptua. At vero eos et accusam et justo duo // dolores et ea rebum. Stet clita kasd gubergren, no sea takimata // sanctus est Lorem ipsum dolor sit amet. // // Implements: ASCOM Telescope interface version: // Author: (XXX) Your N. Here // // Edit Log: // // Date Who Vers Description // ----------- --- ----- ------------------------------------------------------- // dd-mmm-yyyy XXX 6.0.0 Initial edit, created from ASCOM driver template // -------------------------------------------------------------------------------- // // This is used to define code in the template that is specific to one class implementation // unused code canbe deleted and this definition removed. #define Telescope using System; using System.Runtime.InteropServices; using ASCOM; using ASCOM.Astrometry; using ASCOM.Astrometry.AstroUtils; using ASCOM.Utilities; using ASCOM.DeviceInterface; using System.Globalization; using System.Collections; using ASCOM.MeadeAutostar497.Controller; using static System.String; namespace ASCOM.MeadeAutostar497 { // // Your driver's DeviceID is ASCOM.MeadeAutostar497.Telescope // // The Guid attribute sets the CLSID for ASCOM.MeadeAutostar497.Telescope // The ClassInterface/None addribute prevents an empty interface called // _MeadeAutostar497 from being created and used as the [default] interface // // TODO Replace the not implemented exceptions with code to implement the function or // throw the appropriate ASCOM exception. // /// /// ASCOM Telescope Driver for MeadeAutostar497. /// [Guid("58e4fe97-1760-4e22-8ecd-2225876aeefc")] [ClassInterface(ClassInterfaceType.None)] public class Telescope : ITelescopeV3 { private ITelescopeController _telescopeController; /// /// ASCOM DeviceID (COM ProgID) for this driver. /// The DeviceID is used by ASCOM applications to load the driver at runtime. /// internal static string driverID = "ASCOM.MeadeAutostar497.Telescope"; // TODO Change the descriptive string for your driver then remove this line /// /// Driver description that displays in the ASCOM Chooser. /// private static string driverDescription = "Meade Autostar 497 .net"; internal static string comPortProfileName = "COM Port"; // Constants used for Profile persistence internal static string comPortDefault = "COM1"; internal static string traceStateProfileName = "Trace Level"; internal static string traceStateDefault = "false"; internal static string comPort; // Variables to hold the currrent device configuration /// /// Private variable to hold an ASCOM Utilities object /// private Util utilities; /// /// Private variable to hold an ASCOM AstroUtilities object to provide the Range method /// private AstroUtils astroUtilities; /// /// Variable to hold the trace logger object (creates a diagnostic log file with information that you specify) /// internal static TraceLogger tl; /// /// Initializes a new instance of the class. /// Must be public for COM registration. /// public Telescope() { tl = new TraceLogger("", "MeadeAutostar497"); ReadProfile(); // Read device configuration from the ASCOM Profile store tl.LogMessage("Telescope", "Starting initialisation"); utilities = new Util(); //Initialise util object astroUtilities = new AstroUtils(); // Initialise astro utilities object //TODO: Implement your additional construction here _telescopeController = TelescopeController.Instance; tl.LogMessage("Telescope", "Completed initialisation"); } // // PUBLIC COM INTERFACE ITelescopeV3 IMPLEMENTATION // #region Common properties and methods. /// /// Displays the Setup Dialog form. /// If the user clicks the OK button to dismiss the form, then /// the new settings are saved, otherwise the old values are reloaded. /// THIS IS THE ONLY PLACE WHERE SHOWING USER INTERFACE IS ALLOWED! /// public void SetupDialog() { // consider only showing the setup dialog if not connected // or call a different dialog if connected if (IsConnected) { System.Windows.Forms.MessageBox.Show("Already connected, just press OK"); return; } using (SetupDialogForm F = new SetupDialogForm()) { var result = F.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { WriteProfile(); // Persist device configuration values to the ASCOM Profile store } } } public ArrayList SupportedActions { get { tl.LogMessage("SupportedActions Get", "Returning empty arraylist"); return new ArrayList(); } } public string Action(string actionName, string actionParameters) { LogMessage("", "Action {0}, parameters {1} not implemented", actionName, actionParameters); throw new ASCOM.ActionNotImplementedException("Action " + actionName + " is not implemented by this driver"); } public void CommandBlind(string command, bool raw) { CheckConnected("CommandBlind"); // Call CommandString and return as soon as it finishes //this.CommandString(command, raw); // or throw new ASCOM.MethodNotImplementedException("CommandBlind"); // DO NOT have both these sections! One or the other } public bool CommandBool(string command, bool raw) { CheckConnected("CommandBool"); string ret = CommandString(command, raw); // TODO decode the return string and return true or false // or throw new ASCOM.MethodNotImplementedException("CommandBool"); // DO NOT have both these sections! One or the other } public string CommandString(string command, bool raw) { // it's a good idea to put all the low level communication with the device here, // then all communication calls this function // you need something to ensure that only one command is in progress at a time CheckConnected("CommandString"); throw new ASCOM.MethodNotImplementedException("CommandString"); } public void Dispose() { _telescopeController.Connected = false; // Clean up the tracelogger and util objects tl.Enabled = false; tl.Dispose(); tl = null; utilities.Dispose(); utilities = null; astroUtilities.Dispose(); astroUtilities = null; } public bool Connected { get { LogMessage("Connected", "Get {0}", IsConnected); return IsConnected; } set { tl.LogMessage("Connected", "Set {0}", value); if (value == IsConnected) return; if (value) { LogMessage("Connected Set", "Connecting to port {0}", comPort); _telescopeController.Port = comPort; _telescopeController.Connected = true; } else { LogMessage("Connected Set", "Disconnecting from port {0}", comPort); _telescopeController.Connected = false; } } } public string Description { // TODO customise this device description get { tl.LogMessage("Description Get", driverDescription); return driverDescription; } } public string DriverInfo { get { Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; // TODO customise this driver description string driverInfo = Format(CultureInfo.InvariantCulture, "Information about the driver itself. Version: {0}.{1}", version.Major, version.Minor); tl.LogMessage("DriverInfo Get", driverInfo); return driverInfo; } } public string DriverVersion { get { Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; string driverVersion = Format(CultureInfo.InvariantCulture, "{0}.{1}", version.Major, version.Minor); tl.LogMessage("DriverVersion Get", driverVersion); return driverVersion; } } public short InterfaceVersion { // set by the driver wizard get { LogMessage("InterfaceVersion Get", "3"); return Convert.ToInt16("3"); } } public string Name { get { string name = "Meade Autostar 497 .net"; tl.LogMessage("Name Get", name); return name; } } #endregion #region ITelescope Implementation public void AbortSlew() { tl.LogMessage("AbortSlew", "Aborting slew"); _telescopeController.AbortSlew(); } public AlignmentModes AlignmentMode { get { tl.LogMessage("AlignmentMode Get", "Not implemented"); return _telescopeController.AlignmentMode; } } public double Altitude { get { tl.LogMessage("Altitude", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("Altitude", false); } } public double ApertureArea { get { tl.LogMessage("ApertureArea Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("ApertureArea", false); } } public double ApertureDiameter { get { tl.LogMessage("ApertureDiameter Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("ApertureDiameter", false); } } public bool AtHome { get { tl.LogMessage("AtHome", "Get - " + false.ToString()); return false; } } public bool AtPark { get { var atPatk = _telescopeController.AtPark; tl.LogMessage("AtPark", "Get - " + atPatk.ToString()); return atPatk; } } public IAxisRates AxisRates(TelescopeAxes Axis) { tl.LogMessage("AxisRates", "Get - " + Axis.ToString()); return new AxisRates(Axis); } public double Azimuth { get { var az = _telescopeController.Azimuth; tl.LogMessage("Azimuth Get", $"{az}"); return az; } } public bool CanFindHome { get { tl.LogMessage("CanFindHome", "Get - " + false.ToString()); return false; } } public bool CanMoveAxis(TelescopeAxes Axis) { tl.LogMessage("CanMoveAxis", "Get - " + Axis.ToString()); switch (Axis) { case TelescopeAxes.axisPrimary: return true; //RA or AZ case TelescopeAxes.axisSecondary: return true; //Dev or Alt case TelescopeAxes.axisTertiary: return false; //rotator / derotator default: throw new InvalidValueException("CanMoveAxis", Axis.ToString(), "0 to 2"); } } public bool CanPark { get { tl.LogMessage("CanPark", "Get - " + true.ToString()); return true; } } public bool CanPulseGuide { get { tl.LogMessage("CanPulseGuide", "Get - " + true.ToString()); return true; } } public bool CanSetDeclinationRate { get { tl.LogMessage("CanSetDeclinationRate", "Get - " + false.ToString()); return false; } } public bool CanSetGuideRates { get { tl.LogMessage("CanSetGuideRates", "Get - " + false.ToString()); return false; } } public bool CanSetPark { get { tl.LogMessage("CanSetPark", "Get - " + false.ToString()); return false; } } public bool CanSetPierSide { get { tl.LogMessage("CanSetPierSide", "Get - " + false.ToString()); return false; } } public bool CanSetRightAscensionRate { get { tl.LogMessage("CanSetRightAscensionRate", "Get - " + false.ToString()); return false; } } public bool CanSetTracking { get { tl.LogMessage("CanSetTracking", "Get - " + false.ToString()); return false; } } public bool CanSlew { get { tl.LogMessage("CanSlew", "Get - " + true.ToString()); return true; } } public bool CanSlewAltAz { get { tl.LogMessage("CanSlewAltAz", "Get - " + true.ToString()); return true; } } public bool CanSlewAltAzAsync { get { tl.LogMessage("CanSlewAltAzAsync", "Get - " + true.ToString()); return true; } } public bool CanSlewAsync { get { tl.LogMessage("CanSlewAsync", "Get - " + true.ToString()); return true; } } public bool CanSync { get { tl.LogMessage("CanSync", "Get - " + true.ToString()); return true; } } public bool CanSyncAltAz { get { tl.LogMessage("CanSyncAltAz", "Get - " + false.ToString()); return false; } } public bool CanUnpark { get { tl.LogMessage("CanUnpark", "Get - " + false.ToString()); return false; } } public double Declination { get { double declination = 0.0; tl.LogMessage("Declination", "Get - " + utilities.DegreesToDMS(declination, ":", ":")); return declination; } } public double DeclinationRate { get { double declination = 0.0; tl.LogMessage("DeclinationRate", "Get - " + declination.ToString()); return declination; } set { tl.LogMessage("DeclinationRate Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("DeclinationRate", true); } } public PierSide DestinationSideOfPier(double RightAscension, double Declination) { tl.LogMessage("DestinationSideOfPier Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("DestinationSideOfPier", false); } public bool DoesRefraction { get { tl.LogMessage("DoesRefraction Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("DoesRefraction", false); } set { tl.LogMessage("DoesRefraction Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("DoesRefraction", true); } } public EquatorialCoordinateType EquatorialSystem { get { EquatorialCoordinateType equatorialSystem = EquatorialCoordinateType.equTopocentric; tl.LogMessage("DeclinationRate", "Get - " + equatorialSystem.ToString()); return equatorialSystem; } } public void FindHome() { tl.LogMessage("FindHome", "Not implemented"); throw new ASCOM.MethodNotImplementedException("FindHome"); } public double FocalLength { get { tl.LogMessage("FocalLength Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("FocalLength", false); } } public double GuideRateDeclination { get { tl.LogMessage("GuideRateDeclination Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("GuideRateDeclination", false); } set { tl.LogMessage("GuideRateDeclination Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("GuideRateDeclination", true); } } public double GuideRateRightAscension { get { tl.LogMessage("GuideRateRightAscension Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("GuideRateRightAscension", false); } set { tl.LogMessage("GuideRateRightAscension Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("GuideRateRightAscension", true); } } public bool IsPulseGuiding { get { tl.LogMessage("IsPulseGuiding Get", "pulse guiding is synchronous for this driver"); //throw new ASCOM.PropertyNotImplementedException("IsPulseGuiding", false); return false; } } public void MoveAxis(TelescopeAxes Axis, double Rate) { tl.LogMessage("MoveAxis", "Not implemented"); throw new ASCOM.MethodNotImplementedException("MoveAxis"); } public void Park() { tl.LogMessage("Park", "Parking telescope"); _telescopeController.Park(); } public void PulseGuide(GuideDirections Direction, int Duration) { tl.LogMessage("PulseGuide", $"pulse guide direction {Direction} duration {Duration}"); _telescopeController.PulseGuide(Direction, Duration); } public double RightAscension { get { double rightAscension = 0.0; tl.LogMessage("RightAscension", "Get - " + utilities.HoursToHMS(rightAscension)); return rightAscension; } } public double RightAscensionRate { get { double rightAscensionRate = 0.0; tl.LogMessage("RightAscensionRate", "Get - " + rightAscensionRate.ToString()); return rightAscensionRate; } set { tl.LogMessage("RightAscensionRate Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("RightAscensionRate", true); } } public void SetPark() { tl.LogMessage("SetPark", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SetPark"); } public PierSide SideOfPier { get { tl.LogMessage("SideOfPier Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SideOfPier", false); } set { tl.LogMessage("SideOfPier Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SideOfPier", true); } } public double SiderealTime { get { // Now using NOVAS 3.1 double siderealTime = 0.0; using (var novas = new ASCOM.Astrometry.NOVAS.NOVAS31()) { var jd = utilities.DateUTCToJulian(DateTime.UtcNow); novas.SiderealTime(jd, 0, novas.DeltaT(jd), ASCOM.Astrometry.GstType.GreenwichApparentSiderealTime, ASCOM.Astrometry.Method.EquinoxBased, ASCOM.Astrometry.Accuracy.Reduced, ref siderealTime); } // Allow for the longitude siderealTime += SiteLongitude / 360.0 * 24.0; // Reduce to the range 0 to 24 hours siderealTime = astroUtilities.ConditionRA(siderealTime); tl.LogMessage("SiderealTime", "Get - " + siderealTime.ToString()); return siderealTime; } } public double SiteElevation { get { tl.LogMessage("SiteElevation Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SiteElevation", false); } set { tl.LogMessage("SiteElevation Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SiteElevation", true); } } public double SiteLatitude { get { var siteLatitude = _telescopeController.SiteLatitude; tl.LogMessage("SiteLatitude Get", $"{utilities.DegreesToDMS(siteLatitude)}"); return siteLatitude; } set { tl.LogMessage("SiteLatitude Set", $"{utilities.DegreesToDMS(value)}"); _telescopeController.SiteLatitude = value; } } public double SiteLongitude { get { var siteLongitude = _telescopeController.SiteLongitude; tl.LogMessage("SiteLongitude Get", $"{utilities.DegreesToDMS(siteLongitude)}"); return siteLongitude; } set { tl.LogMessage("SiteLongitude Set", $"{utilities.DegreesToDMS(value)}"); _telescopeController.SiteLongitude = value; } } public short SlewSettleTime { get { tl.LogMessage("SlewSettleTime Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SlewSettleTime", false); } set { tl.LogMessage("SlewSettleTime Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SlewSettleTime", true); } } public void SlewToAltAz(double Azimuth, double Altitude) { tl.LogMessage("SlewToAltAz", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SlewToAltAz"); } public void SlewToAltAzAsync(double Azimuth, double Altitude) { tl.LogMessage("SlewToAltAzAsync", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SlewToAltAzAsync"); } public void SlewToCoordinates(double RightAscension, double Declination) { tl.LogMessage("SlewToCoordinates", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SlewToCoordinates"); } public void SlewToCoordinatesAsync(double RightAscension, double Declination) { tl.LogMessage("SlewToCoordinatesAsync", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SlewToCoordinatesAsync"); } public void SlewToTarget() { tl.LogMessage("SlewToTarget", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SlewToTarget"); } public void SlewToTargetAsync() { tl.LogMessage("SlewToTargetAsync", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SlewToTargetAsync"); } public bool Slewing { get { tl.LogMessage("Slewing Get", "Started"); var result = _telescopeController.Slewing; tl.LogMessage("Slewing Get", $"Result = {result}"); return result; } } public void SyncToAltAz(double Azimuth, double Altitude) { tl.LogMessage("SyncToAltAz", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SyncToAltAz"); } public void SyncToCoordinates(double RightAscension, double Declination) { tl.LogMessage("SyncToCoordinates", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SyncToCoordinates"); } public void SyncToTarget() { tl.LogMessage("SyncToTarget", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SyncToTarget"); } public double TargetDeclination { get { tl.LogMessage("TargetDeclination Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("TargetDeclination", false); } set { tl.LogMessage("TargetDeclination Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("TargetDeclination", true); } } public double TargetRightAscension { get { tl.LogMessage("TargetRightAscension Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("TargetRightAscension", false); } set { tl.LogMessage("TargetRightAscension Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("TargetRightAscension", true); } } public bool Tracking { get { //todo implementing this, it exists. bool tracking = true; tl.LogMessage("Tracking", "Get - " + tracking.ToString()); return tracking; } set { tl.LogMessage("Tracking Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("Tracking", true); } } public DriveRates TrackingRate { get { tl.LogMessage("TrackingRate Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("TrackingRate", false); } set { tl.LogMessage("TrackingRate Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("TrackingRate", true); } } public ITrackingRates TrackingRates { get { ITrackingRates trackingRates = new TrackingRates(); tl.LogMessage("TrackingRates", "Get - "); foreach (DriveRates driveRate in trackingRates) { tl.LogMessage("TrackingRates", "Get - " + driveRate.ToString()); } return trackingRates; } } public DateTime UTCDate { get { tl.LogMessage("UTCDate", "Get started"); var utcDate = _telescopeController.utcDate; tl.LogMessage("UTCDate", "Get - " + Format("MM/dd/yy HH:mm:ss", utcDate)); return utcDate; } set { tl.LogMessage("UTCDate", "Set - " + Format("MM/dd/yy HH:mm:ss", value)); _telescopeController.utcDate = value; } } public void Unpark() { tl.LogMessage("Unpark", "Not implemented"); throw new ASCOM.MethodNotImplementedException("Unpark"); } #endregion #region Private properties and methods // here are some useful properties and methods that can be used as required // to help with driver development #region ASCOM Registration // Register or unregister driver for ASCOM. This is harmless if already // registered or unregistered. // /// /// Register or unregister the driver with the ASCOM Platform. /// This is harmless if the driver is already registered/unregistered. /// /// If true, registers the driver, otherwise unregisters it. private static void RegUnregASCOM(bool bRegister) { using (var P = new ASCOM.Utilities.Profile()) { P.DeviceType = "Telescope"; if (bRegister) { P.Register(driverID, driverDescription); } else { P.Unregister(driverID); } } } /// /// This function registers the driver with the ASCOM Chooser and /// is called automatically whenever this class is registered for COM Interop. /// /// Type of the class being registered, not used. /// /// This method typically runs in two distinct situations: /// /// /// In Visual Studio, when the project is successfully built. /// For this to work correctly, the option Register for COM Interop /// must be enabled in the project settings. /// /// During setup, when the installer registers the assembly for COM Interop. /// /// This technique should mean that it is never necessary to manually register a driver with ASCOM. /// [ComRegisterFunction] public static void RegisterASCOM(Type t) { RegUnregASCOM(true); } /// /// This function unregisters the driver from the ASCOM Chooser and /// is called automatically whenever this class is unregistered from COM Interop. /// /// Type of the class being registered, not used. /// /// This method typically runs in two distinct situations: /// /// /// In Visual Studio, when the project is cleaned or prior to rebuilding. /// For this to work correctly, the option Register for COM Interop /// must be enabled in the project settings. /// /// During uninstall, when the installer unregisters the assembly from COM Interop. /// /// This technique should mean that it is never necessary to manually unregister a driver from ASCOM. /// [ComUnregisterFunction] public static void UnregisterASCOM(Type t) { RegUnregASCOM(false); } #endregion /// /// Returns true if there is a valid connection to the driver hardware /// private bool IsConnected => _telescopeController.Connected; /// /// Use this function to throw an exception if we aren't connected to the hardware /// /// private void CheckConnected(string message) { if (!IsConnected) { throw new ASCOM.NotConnectedException(message); } } /// /// Read the device configuration from the ASCOM Profile store /// internal void ReadProfile() { using (Profile driverProfile = new Profile()) { driverProfile.DeviceType = "Telescope"; tl.Enabled = Convert.ToBoolean(driverProfile.GetValue(driverID, traceStateProfileName, Empty, traceStateDefault)); comPort = driverProfile.GetValue(driverID, comPortProfileName, Empty, comPortDefault); } } /// /// Write the device configuration to the ASCOM Profile store /// internal void WriteProfile() { using (Profile driverProfile = new Profile()) { driverProfile.DeviceType = "Telescope"; driverProfile.WriteValue(driverID, traceStateProfileName, tl.Enabled.ToString()); driverProfile.WriteValue(driverID, comPortProfileName, comPort.ToString()); } } /// /// Log helper function that takes formatted strings and arguments /// /// /// /// internal static void LogMessage(string identifier, string message, params object[] args) { var msg = Format(message, args); tl.LogMessage(identifier, msg); } #endregion } }