diff --git a/AstroMath.UnitTests/AstroMath.UnitTests.csproj b/AstroMath.UnitTests/AstroMath.UnitTests.csproj index d066d8f..ad41f58 100644 --- a/AstroMath.UnitTests/AstroMath.UnitTests.csproj +++ b/AstroMath.UnitTests/AstroMath.UnitTests.csproj @@ -54,10 +54,10 @@ - ..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll + ..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll - - ..\packages\Moq.4.10.1\lib\net45\Moq.dll + + ..\packages\Moq.4.12.0\lib\net45\Moq.dll ..\packages\NUnit.3.12.0\lib\net45\nunit.framework.dll @@ -65,11 +65,11 @@ - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - ..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll diff --git a/AstroMath.UnitTests/AstroMathsUnitTests.cs b/AstroMath.UnitTests/AstroMathsUnitTests.cs index cdbe4ad..c6c0082 100644 --- a/AstroMath.UnitTests/AstroMathsUnitTests.cs +++ b/AstroMath.UnitTests/AstroMathsUnitTests.cs @@ -1,5 +1,5 @@ using System; -using ASCOM.Meade.net; +using ASCOM.Meade.net.AstroMaths; using NUnit.Framework; namespace AstroMath.UnitTests @@ -52,16 +52,16 @@ namespace AstroMath.UnitTests public void UTtoGST_book() { DateTime dateTime = new DateTime(1980, 04, 22, 14, 36, 51, 670, DateTimeKind.Utc); - double gst = _astroMath.UTtoGST(dateTime); + double gst = _astroMath.UTtoGst(dateTime); Assert.That(gst, Is.EqualTo(4.667932706211154)); } [Test] - public void UTtoGST() + public void UTtoGst() { DateTime dateTime = new DateTime(2019, 05, 18, 22, 26, 15, DateTimeKind.Utc); - double gst = _astroMath.UTtoGST(dateTime); + double gst = _astroMath.UTtoGst(dateTime); Assert.That(gst, Is.EqualTo(14.191879687876451)); } @@ -71,16 +71,16 @@ namespace AstroMath.UnitTests { double gst = 4.668119; var longitude = -64; - var lst = _astroMath.GSTtoLST(gst, longitude); + var lst = _astroMath.GsTtoLst(gst, longitude); Assert.That(lst, Is.EqualTo(0.4014523333333333)); } [Test] - public void GSTtoLST() + public void GsTtoLst() { double gst = 14.257589512545053; var longitude = -1.7833333333333332; - var lst = _astroMath.GSTtoLST(gst, longitude); + var lst = _astroMath.GsTtoLst(gst, longitude); Assert.That(lst, Is.EqualTo(14.138700623656163)); } diff --git a/AstroMath.UnitTests/Properties/AssemblyInfo.cs b/AstroMath.UnitTests/Properties/AssemblyInfo.cs index 2c0f1a3..fa399cc 100644 --- a/AstroMath.UnitTests/Properties/AssemblyInfo.cs +++ b/AstroMath.UnitTests/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -32,5 +31,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.7.0.0")] -[assembly: AssemblyFileVersion("0.7.0.0")] +[assembly: AssemblyVersion("0.0.0.0")] +[assembly: AssemblyFileVersion("0.0.0.0")] diff --git a/AstroMath.UnitTests/packages.config b/AstroMath.UnitTests/packages.config index 22d8680..605fe2b 100644 --- a/AstroMath.UnitTests/packages.config +++ b/AstroMath.UnitTests/packages.config @@ -1,8 +1,8 @@  - - + + - - + + \ No newline at end of file diff --git a/FocuserTestConsole/Program.cs b/FocuserTestConsole/Program.cs index af644c8..d7cfce5 100644 --- a/FocuserTestConsole/Program.cs +++ b/FocuserTestConsole/Program.cs @@ -9,13 +9,10 @@ #define UseChooser using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading; using ASCOM.DriverAccess; -namespace ASCOM +namespace ASCOM.MeadeGeneric { class Program { @@ -24,11 +21,11 @@ namespace ASCOM // Uncomment the code that's required #if UseChooser // choose the device - string id = ASCOM.DriverAccess.Focuser.Choose("ASCOM.MeadeGeneric.Focuser"); + string id = Focuser.Choose("ASCOM.MeadeGeneric.Focuser"); if (string.IsNullOrEmpty(id)) return; // create this device - ASCOM.DriverAccess.Focuser device = new ASCOM.DriverAccess.Focuser(id); + Focuser device = new Focuser(id); #else // this can be replaced by this code, it avoids the chooser and creates the driver class directly. ASCOM.DriverAccess.Telescope device = new ASCOM.DriverAccess.Telescope("ASCOM.MeadeGeneric.Telescope"); diff --git a/FocuserTestConsole/Properties/AssemblyInfo.cs b/FocuserTestConsole/Properties/AssemblyInfo.cs index 1349406..fcf75bf 100644 --- a/FocuserTestConsole/Properties/AssemblyInfo.cs +++ b/FocuserTestConsole/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -32,5 +31,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion("0.7.0.0")] -[assembly: AssemblyFileVersion("0.7.0.0")] +[assembly: AssemblyVersion("0.0.0.0")] +[assembly: AssemblyFileVersion("0.0.0.0")] diff --git a/Meade.net.Common/Meade.net.Common.csproj b/Meade.net.Common/Meade.net.Common.csproj new file mode 100644 index 0000000..070032c --- /dev/null +++ b/Meade.net.Common/Meade.net.Common.csproj @@ -0,0 +1,46 @@ + + + + + Debug + AnyCPU + {7A63F045-FC76-47B9-9DC6-59FA4B758FBB} + Library + Properties + Meade.net.Common + Meade.net.Common + v4.0 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Meade.net.Common/Properties/AssemblyInfo.cs b/Meade.net.Common/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..9f4880f --- /dev/null +++ b/Meade.net.Common/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Meade.net.Common")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Meade.net.Common")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("7a63f045-fc76-47b9-9dc6-59fa4b758fbb")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Meade.net.Setup/Config.wxi b/Meade.net.Setup/Config.wxi index 8e64544..aed1c3c 100644 --- a/Meade.net.Setup/Config.wxi +++ b/Meade.net.Setup/Config.wxi @@ -43,6 +43,6 @@ - - + + \ No newline at end of file diff --git a/Meade.net.Telescope.UnitTests/BootstrapAscomProfileStore.ps1 b/Meade.net.Telescope.UnitTests/BootstrapAscomProfileStore.ps1 new file mode 100644 index 0000000..213c64d --- /dev/null +++ b/Meade.net.Telescope.UnitTests/BootstrapAscomProfileStore.ps1 @@ -0,0 +1,36 @@ +<# +This script initializes a bare minimum set of registry entries required for ASCOM.Utilities.Profile to work +without throwing any exceptions. When building on a build server, or on a computer without the ASCOM Platform installed, +it may be useful to execute this script as a build step prior to running any unit tests, or calling any code that relies on +ASCOM.Utilities.Profile. The alternative is to install the ASCOM Platform on the build agent. + +NOTE: This script equires elevated permissions because it creates registry keys in the LocalMachine hive. +#> + +$wow = Test-Path HKLM:\SOFTWARE\Wow6432Node +if ($wow) + { + $root = "HKLM:\SOFTWARE\Wow6432Node" + } +else + { + $root = "HKLM:\SOFTWARE" + } +$ascomRoot = $root + "\ASCOM" + +if (Test-Path $ascomRoot) + { + <# Don't upset an already-existing ASCOM registry #> + exit + } + +<# Create the ASCOM root key and set it's ACL to allow all users read/write access #> +New-Item -Path $root -Name ASCOM –Force +$ascomAcl = Get-Acl $ascomRoot +$aclRule = New-Object System.Security.AccessControl.RegistryAccessRule ("Users","FullControl","Allow") +$ascomAcl.SetAccessRule($aclRule) +$ascomAcl | Set-Acl -Path $ascomRoot + +<# Now create the bare minimum keys required so that ASCOM.Utilities.Profile doesn't crash and burn #> +New-ItemProperty -Path $ascomRoot -Name PlatformVersion -Value "6.1" -PropertyType String –Force +New-ItemProperty -Path $ascomRoot -Name SerTraceFile -Value "C:\SerialTraceAuto.txt" -PropertyType String –Force diff --git a/Meade.net.Telescope.UnitTests/Meade.net.Telescope.UnitTests.csproj b/Meade.net.Telescope.UnitTests/Meade.net.Telescope.UnitTests.csproj new file mode 100644 index 0000000..23613aa --- /dev/null +++ b/Meade.net.Telescope.UnitTests/Meade.net.Telescope.UnitTests.csproj @@ -0,0 +1,142 @@ + + + + + + Debug + AnyCPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33} + Library + Properties + Meade.net.Telescope.UnitTests + Meade.net.Telescope.UnitTests + v4.7.2 + 512 + true + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + x86 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Astrometry.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Attributes.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Cache.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Controls.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DeviceInterfaces.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DriverAccess.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Exceptions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Internal.Extensions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.SettingsProvider.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.Video.dll + + + ..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll + + + ..\packages\Moq.4.12.0\lib\net45\Moq.dll + + + ..\packages\NUnit.3.12.0\lib\net40\nunit.framework.dll + + + + + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + + + + + + + + + + + + {64308775-bd4a-469c-bcab-3ed830b811af} + Meade.net.Telescope + + + {3689a2cb-94c5-4012-a5cf-7e7d1dd27143} + Meade.net + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + \ No newline at end of file diff --git a/Meade.net.Telescope.UnitTests/Properties/AssemblyInfo.cs b/Meade.net.Telescope.UnitTests/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..3d960cb --- /dev/null +++ b/Meade.net.Telescope.UnitTests/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Meade.net.Telescope.UnitTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Meade.net.Telescope.UnitTests")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("b7eeeefd-5bff-443d-981c-7b8ab5dfde33")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.0.0.0")] +[assembly: AssemblyFileVersion("0.0.0.0")] diff --git a/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs b/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs new file mode 100644 index 0000000..1f29a92 --- /dev/null +++ b/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs @@ -0,0 +1,2153 @@ +using System; +using ASCOM; +using ASCOM.Astrometry.AstroUtils; +using ASCOM.DeviceInterface; +using ASCOM.Meade.net; +using ASCOM.Meade.net.AstroMaths; +using ASCOM.Meade.net.Wrapper; +using ASCOM.Utilities.Interfaces; +using Moq; +using NUnit.Framework; +using InvalidOperationException = ASCOM.InvalidOperationException; + +namespace Meade.net.Telescope.UnitTests +{ + [TestFixture] + public class TelescopeUnitTests + { + private ASCOM.Meade.net.Telescope _telescope; + private Mock _utilMock; + private Mock _utilExtraMock; + private Mock _astroUtilsMock; + private Mock _sharedResourcesWrapperMock; + private Mock _astroMathsMock; + + private ProfileProperties _profileProperties; + + [SetUp] + public void Setup() + { + _profileProperties = new ProfileProperties(); + _profileProperties.TraceLogger = false; + _profileProperties.ComPort = "TestCom1"; + + _utilMock = new Mock(); + _utilExtraMock = new Mock(); + _astroUtilsMock = new Mock(); + + _sharedResourcesWrapperMock = new Mock(); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GZ#")).Returns("DDD*MM’SS"); + _sharedResourcesWrapperMock.Setup(x => x.Autostar497).Returns(() => "AUTOSTAR"); + _sharedResourcesWrapperMock.Setup(x => x.Autostar49731Ee).Returns(() => "31Ee"); + _sharedResourcesWrapperMock.Setup(x => x.Autostar49743Eg) .Returns(() => "43Eg"); + + _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny())).Callback(action => { action(); }); + _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny>())).Returns>( (func) => func()); + _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny>())).Returns>((func) => func()); + + + _sharedResourcesWrapperMock.Setup(x => x.ReadProfile()).Returns(_profileProperties); + + _astroMathsMock = new Mock(); + + _telescope = new ASCOM.Meade.net.Telescope(_utilMock.Object, _utilExtraMock.Object, _astroUtilsMock.Object, + _sharedResourcesWrapperMock.Object, _astroMathsMock.Object); + } + + private void ConnectTelescope() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.Autostar497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.Autostar49731Ee); + _telescope.Connected = true; + } + + [Test] + public void CheckThatClassCreatedProperly() + { + Assert.That(_telescope, Is.Not.Null); + } + + [Test] + public void NotConnectedByDefault() + { + Assert.That(_telescope.Connected, Is.False); + } + + [Test] + public void SetupDialog() + { + _sharedResourcesWrapperMock.Verify(x => x.ReadProfile(), Times.Once); + + _telescope.SetupDialog(); + + _sharedResourcesWrapperMock.Verify(x => x.SetupDialog(), Times.Once); + _sharedResourcesWrapperMock.Verify(x => x.ReadProfile(), Times.Exactly(2)); + } + + [Test] + public void SupportedActions() + { + var supportedActions = _telescope.SupportedActions; + + Assert.That(supportedActions, Is.Not.Null); + Assert.That(supportedActions.Count, Is.EqualTo(1)); + Assert.That(supportedActions.Contains("handbox"), Is.True); + } + + [Test] + public void Action_WhenNotConnected_ThrowsNotConnectedException() + { + var exception = Assert.Throws(() => { var actualResult = _telescope.Action(string.Empty, string.Empty); }); + Assert.That(exception.Message,Is.EqualTo("Not connected to telescope when trying to execute: Action")); + } + + [Test] + public void Action_Handbox_ReadDisplay() + { + string expectedResult = "test result string"; + _sharedResourcesWrapperMock.Setup(x => x.SendString(":ED#")).Returns(expectedResult); + _telescope.Connected = true; + + + + var actualResult = _telescope.Action("handbox", "readdisplay"); + + _sharedResourcesWrapperMock.Verify(x => x.SendString(":ED#"), Times.Once); + Assert.That(actualResult, Is.EqualTo(expectedResult)); + } + + [TestCase("enter", ":EK13#")] + [TestCase("mode", ":EK9#")] + [TestCase("longMode", ":EK11#")] + [TestCase("goto", ":EK24#")] + [TestCase("0", ":EK48#")] + [TestCase("1", ":EK49#")] + [TestCase("2", ":EK50#")] + [TestCase("3", ":EK51#")] + [TestCase("4", ":EK52#")] + [TestCase("5", ":EK53#")] + [TestCase("6", ":EK54#")] + [TestCase("7", ":EK55#")] + [TestCase("8", ":EK56#")] + [TestCase("9", ":EK57#")] + [TestCase("up", ":EK94#")] + [TestCase("down", ":EK118#")] + [TestCase("back", ":EK87#")] + [TestCase("forward", ":EK69#")] + [TestCase("?", ":EK63#")] + public void Action_Handbox_blindCommands(string action, string expectedString) + { + ConnectTelescope(); + + _telescope.Action("handbox", action); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(expectedString), Times.Once); + } + + [Test] + public void Action_Handbox_nonExistantAction() + { + ConnectTelescope(); + + string actionName = "handbox"; + string actionParameters = "doesnotexist"; + var exception = Assert.Throws(() => { _telescope.Action(actionName, actionParameters); }); + + Assert.That(exception.Message, Is.EqualTo($"Action {actionName}({actionParameters}) is not implemented in this driver is not implemented in this driver.")); + } + + [Test] + public void Action_nonExistantAction() + { + ConnectTelescope(); + + string actionName = "doesnotexist"; + var exception = Assert.Throws(() => { _telescope.Action(actionName, string.Empty); }); + + Assert.That(exception.Message, Is.EqualTo($"Action {actionName} is not implemented in this driver is not implemented in this driver.")); + } + + [Test] + public void CommandBlind_WhenNotConnected_ThenThrowsNotConnectedException() + { + string expectedMessage = "test blind Message"; + var exception = Assert.Throws(() => { _telescope.CommandBlind(expectedMessage, true); }); + + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: CommandBlind")); + } + + [Test] + public void CommandBlind_WhenConnected_ThenSendsExpectedMessage() + { + string expectedMessage = "test blind Message"; + + ConnectTelescope(); + + _telescope.CommandBlind(expectedMessage, true); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(expectedMessage), Times.Once); + } + + [Test] + public void CommandBool_WhenNotConnected_ThenThrowsNotConnectedException() + { + string expectedMessage = "test blind Message"; + var exception = Assert.Throws(() => { _telescope.CommandBool(expectedMessage, true); }); + + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: CommandBool")); + } + + [Test] + public void CommandBool_WhenConnected_ThenSendsExpectedMessage() + { + string expectedMessage = "test blind Message"; + + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.CommandBool(expectedMessage, true); }); + + Assert.That(exception.Message, Is.EqualTo("Method CommandBool is not implemented in this driver.")); + } + + [Test] + public void CommandString_WhenNotConnected_ThenThrowsNotConnectedException() + { + string expectedMessage = "test blind Message"; + var exception = Assert.Throws(() => { _telescope.CommandString(expectedMessage, true); }); + + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: CommandString")); + } + + [Test] + public void CommandString_WhenConnected_ThenSendsExpectedMessage() + { + string expectedMessage = "expected result message"; + string sendMessage = "test blind Message"; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(sendMessage)).Returns(() => expectedMessage); + + var actualMessage = _telescope.CommandString(sendMessage, true); + + _sharedResourcesWrapperMock.Verify(x => x.SendString(sendMessage), Times.Once); + Assert.That(actualMessage, Is.EqualTo(expectedMessage)); + } + + [TestCase(true)] + [TestCase(false)] + public void Connected_Get_ReturnsExpectedValue(bool expectedConnected) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.Autostar497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.Autostar49731Ee); + _telescope.Connected = expectedConnected; + + Assert.That(_telescope.Connected, Is.EqualTo(expectedConnected)); + } + + + [Test] + public void Connected_Set_SettingTrueWhenTrue_ThenDoesNothing() + { + ConnectTelescope(); + _sharedResourcesWrapperMock.Verify( x => x.Connect(It.IsAny()),Times.Once); + + //act + _telescope.Connected = true; + + //assert + _sharedResourcesWrapperMock.Verify(x => x.Connect(It.IsAny()), Times.Once); + } + + [Test] + public void Connected_Set_SettingFalseWhenTrue_ThenDisconnects() + { + ConnectTelescope(); + _sharedResourcesWrapperMock.Verify(x => x.Connect(It.IsAny()), Times.Once); + + //act + _telescope.Connected = false; + + //assert + _sharedResourcesWrapperMock.Verify(x => x.Disconnect(It.IsAny()), Times.Once()); + } + + [Test] + public void Connected_Set_WhenFailsToConnect_ThenDisconnects() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.Autostar497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.Autostar49731Ee); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(It.IsAny())).Throws(new Exception("TestFailed")); + + //act + _telescope.Connected = true; + + //assert + _sharedResourcesWrapperMock.Verify(x => x.Disconnect(It.IsAny()), Times.Once()); + } + + [TestCase("AUTOSTAR", "30Ab", false)] + [TestCase("AUTOSTAR","31Ee", true)] + [TestCase("AUTOSTAR", "43Eg", true)] + [TestCase("AUTOSTAR II", "", false)] + public void IsNewPulseGuidingSupported_ThenIsSupported_ThenReturnsTrue(string productName, string firmware, bool isSupported) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(productName); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(firmware); + + var result = _telescope.IsNewPulseGuidingSupported(); + + Assert.That(result, Is.EqualTo(isSupported)); + } + + [Test] + public void SetLongFormatFalse_WhenTelescopeReturnsShortFormat_ThenDoesNothing() + { + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GZ#")).Returns("DDD*MM"); + _telescope.SetLongFormat(false); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":U#"),Times.Never); + } + + [Test] + public void SetLongFormatFalse_WhenTelescopeReturnsLongFormat_ThenTogglesPrecision() + { + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GZ#")).Returns("DDD*MM’SS"); + _telescope.SetLongFormat(false); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":U#"), Times.Once); + } + + [Test] + public void SetLongFormatTrue_WhenTelescopeReturnsLongFormat_ThenDoesNothing() + { + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GZ#")).Returns("DDD*MM’SS"); + _telescope.SetLongFormat(true); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":U#"), Times.Never); + } + + [Test] + public void SetLongFormatTrue_WhenTelescopeReturnsShortFormat_ThenTogglesPrecision() + { + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GZ#")).Returns("DDD*MM"); + _telescope.SetLongFormat(true); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":U#"), Times.Once); + } + + [Test] + public void SelectSite_WhenNewSiteToLow_ThenThrowsException() + { + var site = 0; + var result = Assert.Throws(() => { _telescope.SelectSite(site); }); + + Assert.That(result.Message, Is.EqualTo($"Site cannot be lower than 1\r\nParameter name: site\r\nActual value was {site}.")); + } + + [Test] + public void SelectSite_WhenNewSiteToHigh_ThenThrowsException() + { + var site = 5; + var result = Assert.Throws(() => { _telescope.SelectSite(site); }); + + Assert.That(result.Message, Is.EqualTo($"Site cannot be higher than 4\r\nParameter name: site\r\nActual value was {site}.")); + } + + [TestCase(1)] + [TestCase(2)] + [TestCase(3)] + [TestCase(4)] + public void SelectSite_WhenNewSiteToHigh_ThenThrowsException(int site) + { + _telescope.SelectSite(site); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind($":W{site}#"), Times.Once); + } + + [Test] + public void Description_Get() + { + var expectedDescription = "Meade Generic"; + + var description = _telescope.Description; + + Assert.That(description, Is.EqualTo(expectedDescription)); + } + + [Test] + public void DriverVersion_Get() + { + Version version = System.Reflection.Assembly.GetAssembly(typeof(ASCOM.Meade.net.Telescope)).GetName().Version; + + string exptectedDriverInfo = $"{version.Major}.{version.Minor}.{version.Revision}.{version.Build}"; + + var driverVersion = _telescope.DriverVersion; + + Assert.That(driverVersion, Is.EqualTo(exptectedDriverInfo)); + } + + [Test] + public void DriverInfo_Get() + { + Version version = System.Reflection.Assembly.GetAssembly(typeof(ASCOM.Meade.net.Telescope)).GetName().Version; + + string exptectedDriverInfo = $"{_telescope.Description} .net driver. Version: {_telescope.DriverVersion}"; + + var driverInfo = _telescope.DriverInfo; + + Assert.That(driverInfo, Is.EqualTo(exptectedDriverInfo)); + } + + [Test] + public void InterfaceVersion_Get() + { + var interfaceVersion = _telescope.InterfaceVersion; + Assert.That(interfaceVersion, Is.EqualTo(3)); + + Assert.That(_telescope, Is.AssignableTo()); + } + + [Test] + public void Name_Get() + { + string expectedName = "Meade Generic"; + + var name = _telescope.Name; + + Assert.That(name, Is.EqualTo(expectedName)); + } + + [Test] + public void AlignmentMode_Get_WhenNotConnected_ThrowsException() + { + var exception = Assert.Throws(() => { var actualResult = _telescope.AlignmentMode; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: AlignmentMode Get")); + } + + + [TestCase("A", AlignmentModes.algAltAz)] + [TestCase("P", AlignmentModes.algPolar)] + [TestCase("G", AlignmentModes.algGermanPolar)] + public void AlignmentMode_Get_WhenScopeInAltAz_ReturnsAltAz(string telescopeMode, AlignmentModes alignmentMode) + { + ConnectTelescope(); + + const char ack = (char)6; + _sharedResourcesWrapperMock.Setup(x => x.SendChar(ack.ToString())).Returns(telescopeMode); + + var actualResult = _telescope.AlignmentMode; + + Assert.That(actualResult, Is.EqualTo(alignmentMode)); + } + + [Test] + public void AlignmentMode_Get_WhenUnknownAlignmentMode_ThrowsException() + { + ConnectTelescope(); + + Assert.Throws(() => { var actualResult = _telescope.AlignmentMode; }); + } + + [Test] + public void AlignmentMode_Set_WhenNotConnected_ThrowsException() + { + var exception = Assert.Throws(() => { _telescope.AlignmentMode = AlignmentModes.algAltAz; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: AlignmentMode Set")); + } + + [TestCase("AUTOSTAR", "43Eg", AlignmentModes.algAltAz, ":AA#")] + [TestCase("AUTOSTAR", "43Eg", AlignmentModes.algPolar, ":AP#")] + [TestCase("AUTOSTAR", "43Eg", AlignmentModes.algGermanPolar, ":AP#")] + public void AlignmentMode_Set_WhenConnected_ThenSendsExpectedCommand(string productName, string firmware, AlignmentModes alignmentMode, string expectedCommand) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(productName); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(firmware); + _telescope.Connected = true; + + _telescope.AlignmentMode = alignmentMode; + + _sharedResourcesWrapperMock.Verify( x => x.SendBlind(expectedCommand), Times.Once); + } + + [TestCase("AUTOSTAR", "43Ef")] + public void AlignmentMode_Set_WhenAutostarFirmwareToLow_ThenThrowsException(string productName, string firmware ) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(productName); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(firmware); + _telescope.Connected = true; + + var excpetion = Assert.Throws(() => { _telescope.AlignmentMode = AlignmentModes.algAltAz; }); + + Assert.That(excpetion.Property, Is.EqualTo("AlignmentMode")); + Assert.That(excpetion.AccessorSet, Is.True); + } + + [Test] + public void ApertureArea_Get_ThrowsNotImplementedException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.ApertureArea; }); + + Assert.That(excpetion.Property, Is.EqualTo("ApertureArea")); + Assert.That(excpetion.AccessorSet, Is.False); + } + + [Test] + public void ApertureDiameter_Get_ThrowsNotImplementedException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.ApertureDiameter; }); + + Assert.That(excpetion.Property, Is.EqualTo("ApertureDiameter")); + Assert.That(excpetion.AccessorSet, Is.False); + } + + [Test] + public void AtHome_Get_ReturnsFalse() + { + var result = _telescope.AtHome; + + Assert.That(result, Is.False); + } + + [Test] + public void AtPark_Get_WhenNotParked_ThenReturnsFalse() + { + var result = _telescope.AtPark; + + Assert.That(result, Is.False); + } + + [Test] + public void AtPark_Get_WhenParked_ThenReturnsTrue() + { + ConnectTelescope(); + _telescope.Park(); + + var result = _telescope.AtPark; + + Assert.That(result, Is.True); + } + + [TestCase(TelescopeAxes.axisPrimary, 4)] + [TestCase(TelescopeAxes.axisSecondary, 4)] + [TestCase(TelescopeAxes.axisTertiary, 0)] + public void AxisRates_ReturnsExpectedResult(TelescopeAxes axis, int expectedCount) + { + var result = _telescope.AxisRates(axis); + + Assert.That(result.Count, Is.EqualTo(expectedCount)); + } + + [Test] + public void CanFindHome_Get_ReturnsFalse() + { + var result = _telescope.CanFindHome; + + Assert.That(result, Is.False); + } + + [TestCase(TelescopeAxes.axisPrimary, true)] + [TestCase(TelescopeAxes.axisSecondary, true)] + [TestCase(TelescopeAxes.axisTertiary, false)] + public void CanMoveAxis_ReturnsExpectedResult(TelescopeAxes axis, bool expected) + { + var result = _telescope.CanMoveAxis(axis); + + Assert.That(result, Is.EqualTo(expected)); + } + + [Test] + public void CanPark_Get_ReturnsTrue() + { + var result = _telescope.CanPark; + + Assert.That(result, Is.True); + } + + [Test] + public void CanPulseGuide_Get_ReturnsTrue() + { + var result = _telescope.CanPulseGuide; + + Assert.That(result, Is.True); + } + + [Test] + public void CanSetDeclinationRate_Get_ReturnsFalse() + { + var result = _telescope.CanSetDeclinationRate; + + Assert.That(result, Is.False); + } + + [Test] + public void CanSetGuideRates_Get_ReturnsFalse() + { + var result = _telescope.CanSetGuideRates; + + Assert.That(result, Is.False); + } + + [Test] + public void CanSetPark_Get_ReturnsFalse() + { + var result = _telescope.CanSetPark; + + Assert.That(result, Is.False); + } + + [Test] + public void CanSetPierSide_Get_ReturnsFalse() + { + var result = _telescope.CanSetPierSide; + + Assert.That(result, Is.False); + } + + [Test] + public void CanSetRightAscensionRate_Get_ReturnsFalse() + { + var result = _telescope.CanSetRightAscensionRate; + + Assert.That(result, Is.False); + } + + [Test] + public void CanSetTracking_Get_ReturnsTrue() + { + var result = _telescope.CanSetTracking; + + Assert.That(result, Is.True); + } + + [Test] + public void CanSlew_Get_ReturnsTrue() + { + var result = _telescope.CanSlew; + + Assert.That(result, Is.True); + } + + [Test] + public void CanSlewAltAz_Get_ReturnsTrue() + { + var result = _telescope.CanSlewAltAz; + + Assert.That(result, Is.True); + } + + [Test] + public void CanSlewAltAzAsync_Get_ReturnsTrue() + { + var result = _telescope.CanSlewAltAzAsync; + + Assert.That(result, Is.True); + } + + [Test] + public void CanSlewAsync_Get_ReturnsTrue() + { + var result = _telescope.CanSlewAsync; + + Assert.That(result, Is.True); + } + + [Test] + public void CanSync_Get_ReturnsTrue() + { + var result = _telescope.CanSync; + + Assert.That(result, Is.True); + } + + [Test] + public void CanSyncAltAz_Get_ReturnsFalse() + { + var result = _telescope.CanSyncAltAz; + + Assert.That(result, Is.False); + } + + [Test] + public void CanUnpark_Get_ReturnsFalse() + { + var result = _telescope.CanUnpark; + + Assert.That(result, Is.False); + } + + [Test] + public void Declination_Get_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { var actualResult = _telescope.Declination; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: Declination Get")); + } + + [TestCase("s12*34")] + [TestCase("s12*34’56")] + public void Declination_Get_WhenConnected_ThenReadsValueFromScope(string declincationString) + { + var expectedResult = 12.34; + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GD#")).Returns(declincationString); + _utilMock.Setup(x => x.DMSToDegrees(declincationString)).Returns(expectedResult); + + var actualResult = _telescope.Declination; + Assert.That(actualResult, Is.EqualTo(expectedResult)); + } + + [Test] + public void DeclinationRate_Get_ThenReturns0() + { + var actualResult = _telescope.DeclinationRate; + + Assert.That(actualResult, Is.EqualTo(0)); + } + + [Test] + public void DeclinationRate_Set_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.DeclinationRate = 0; }); + + Assert.That(excpetion.Property, Is.EqualTo("DeclinationRate")); + Assert.That(excpetion.AccessorSet, Is.True); + } + + [Test] + public void DestinationSideOfPier_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.DestinationSideOfPier(0,0); }); + + Assert.That(excpetion.Method, Is.EqualTo("DestinationSideOfPier")); + } + + [Test] + public void DoesRefraction_Get_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.DoesRefraction; }); + + Assert.That(excpetion.Property, Is.EqualTo("DoesRefraction")); + Assert.That(excpetion.AccessorSet, Is.False); + } + + [Test] + public void DoesRefraction_Set_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.DoesRefraction = true; }); + + Assert.That(excpetion.Property, Is.EqualTo("DoesRefraction")); + Assert.That(excpetion.AccessorSet, Is.True); + } + + [Test] + public void EquatorialSystem_Get_ReturnsExpectedValue() + { + var actualResult = _telescope.EquatorialSystem; + + Assert.That(actualResult, Is.EqualTo(EquatorialCoordinateType.equTopocentric)); + } + + [Test] + public void FindHome_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.FindHome();}); + + Assert.That(excpetion.Method, Is.EqualTo("FindHome")); + } + + [Test] + public void FocalLength_Get_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.FocalLength; }); + + Assert.That(excpetion.Property, Is.EqualTo("FocalLength")); + Assert.That(excpetion.AccessorSet, Is.False); + } + + [Test] + public void GuideRateDeclination_Get_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.GuideRateDeclination; }); + + Assert.That(excpetion.Property, Is.EqualTo("GuideRateDeclination")); + Assert.That(excpetion.AccessorSet, Is.False); + } + + [Test] + public void GuideRateDeclination_Set_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.GuideRateDeclination = 0; }); + + Assert.That(excpetion.Property, Is.EqualTo("GuideRateDeclination")); + Assert.That(excpetion.AccessorSet, Is.True); + } + + [Test] + public void GuideRateRightAscension_Get_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.GuideRateRightAscension; }); + + Assert.That(excpetion.Property, Is.EqualTo("GuideRateRightAscension")); + Assert.That(excpetion.AccessorSet, Is.False); + } + + [Test] + public void GuideRateRightAscension_Set_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.GuideRateRightAscension = 0; }); + + Assert.That(excpetion.Property, Is.EqualTo("GuideRateRightAscension")); + Assert.That(excpetion.AccessorSet, Is.True); + } + + [Test] + public void IsPulseGuiding_Get_ReturnsFalse() + { + var result = _telescope.IsPulseGuiding; + + Assert.That(result, Is.False); + } + + + [Test] + public void MoveAxis_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.MoveAxis(TelescopeAxes.axisPrimary, 0); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: MoveAxis")); + } + + [TestCase( 0, "", TelescopeAxes.axisPrimary)] + [TestCase( 1, ":RG#", TelescopeAxes.axisPrimary)] + [TestCase(-1, ":RG#", TelescopeAxes.axisPrimary)] + [TestCase( 2, ":RC#", TelescopeAxes.axisPrimary)] + [TestCase(-2, ":RC#", TelescopeAxes.axisPrimary)] + [TestCase( 3, ":RM#", TelescopeAxes.axisPrimary)] + [TestCase(-3, ":RM#", TelescopeAxes.axisPrimary)] + [TestCase( 4, ":RS#", TelescopeAxes.axisPrimary)] + [TestCase(-4, ":RS#", TelescopeAxes.axisPrimary)] + [TestCase(0, "", TelescopeAxes.axisSecondary)] + [TestCase(1, ":RG#", TelescopeAxes.axisSecondary)] + [TestCase(-1, ":RG#", TelescopeAxes.axisSecondary)] + [TestCase(2, ":RC#", TelescopeAxes.axisSecondary)] + [TestCase(-2, ":RC#", TelescopeAxes.axisSecondary)] + [TestCase(3, ":RM#", TelescopeAxes.axisSecondary)] + [TestCase(-3, ":RM#", TelescopeAxes.axisSecondary)] + [TestCase(4, ":RS#", TelescopeAxes.axisSecondary)] + [TestCase(-4, ":RS#", TelescopeAxes.axisSecondary)] + public void MoveAxis_WhenConnected_ThenExecutesCorrectCommandSequence(double rate, string slewRateCommand, TelescopeAxes axis) + { + ConnectTelescope(); + + _telescope.MoveAxis(axis, rate); + + if (slewRateCommand != string.Empty) + _sharedResourcesWrapperMock.Verify( x => x.SendBlind(slewRateCommand), Times.Once); + else + { + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":RG#"), Times.Never); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":RC#"), Times.Never); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":RM#"), Times.Never); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":RS#"), Times.Never); + } + + switch (axis) + { + case TelescopeAxes.axisPrimary: + if (rate == 0) + { + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":Qe#"), Times.Once); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":Qw#"), Times.Once); + } + else if (rate > 0) + { + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":Me#"), Times.Once); + } + else + { + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":Mw#"), Times.Once); + } + break; + case TelescopeAxes.axisSecondary: + if (rate == 0) + { + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":Qn#"), Times.Once); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":Qs#"), Times.Once); + } + else if (rate > 0) + { + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":Mn#"), Times.Once); + } + else + { + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":Ms#"), Times.Once); + } + break; + default: + Assert.Fail("This should never happen"); + break; + } + } + + [Test] + public void MoveAxis_WhenRateTooHigh_ThenThrowsException() + { + var testRate = 5; + + ConnectTelescope(); + + var exception = Assert.Throws( () => { _telescope.MoveAxis(TelescopeAxes.axisTertiary, testRate); }); + + Assert.That(exception.Message, Is.EqualTo($"Rate {testRate} not supported")); + } + + [Test] + public void MoveAxis_WhenTertiaryAxis_ThenThrowsException() + { + var testRate = 0; + + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.MoveAxis(TelescopeAxes.axisTertiary, testRate); }); + + Assert.That(exception.Message, Is.EqualTo($"Can not move this axis.")); + } + + [Test] + public void Park_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.Park(); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: Park")); + } + + [Test] + public void Park_WhenNotParked_ThenSendsParkCommand() + { + ConnectTelescope(); + Assert.That(_telescope.AtPark, Is.False); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":hP#"), Times.Never); + + _telescope.Park(); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":hP#"), Times.Once); + Assert.That(_telescope.AtPark, Is.True); + } + + [Test] + public void Park_WhenParked_ThenDoesNothing() + { + ConnectTelescope(); + + _telescope.Park(); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":hP#"), Times.Once); + Assert.That(_telescope.AtPark, Is.True); + + + //act + _telescope.Park(); + + //no change from previous state. + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":hP#"), Times.Once); + Assert.That(_telescope.AtPark, Is.True); + } + + [Test] + public void PulseGuide_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.PulseGuide(GuideDirections.guideEast,0); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: PulseGuide")); + } + + [TestCase(GuideDirections.guideEast)] + [TestCase(GuideDirections.guideWest)] + [TestCase(GuideDirections.guideNorth)] + [TestCase(GuideDirections.guideSouth)] + public void PulseGuide_WhenConnectedAndNewerPulseGuidingAvailable_ThenSendsNewCommandsAndWaits(GuideDirections direction) + { + var duration = 0; + ConnectTelescope(); + + _telescope.PulseGuide(direction, 0); + + string d = string.Empty; + switch (direction) + { + case GuideDirections.guideEast: + d = "e"; + break; + case GuideDirections.guideWest: + d = "w"; + break; + case GuideDirections.guideNorth: + d = "n"; + break; + case GuideDirections.guideSouth: + d = "s"; + break; + } + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind($":Mg{d}{duration:0000}#")); + _utilMock.Verify( x => x.WaitForMilliseconds(duration), Times.Once); + } + + [TestCase(GuideDirections.guideEast)] + [TestCase(GuideDirections.guideWest)] + [TestCase(GuideDirections.guideNorth)] + [TestCase(GuideDirections.guideSouth)] + public void PulseGuide_WhenConnectedAndNewerPulseGuidingNotAvailable_ThenSendsOldCommandsAndWaits(GuideDirections direction) + { + var duration = 0; + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.Autostar497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => "31Ed"); + _telescope.Connected = true; + + _telescope.PulseGuide(direction, 0); + + string d = string.Empty; + switch (direction) + { + case GuideDirections.guideEast: + d = "e"; + break; + case GuideDirections.guideWest: + d = "w"; + break; + case GuideDirections.guideNorth: + d = "n"; + break; + case GuideDirections.guideSouth: + d = "s"; + break; + } + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(":RG#")); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind($":M{d}#")); + _utilMock.Verify(x => x.WaitForMilliseconds(duration), Times.Once); + _sharedResourcesWrapperMock.Verify(x => x.SendBlind($":Q{d}#")); + } + + [Test] + public void RightAscension_Get_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _telescope.RightAscension; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: RightAscension Get")); + } + + [Test] + public void RightAscension_Get_WhenConnected_ThenReturnsExpectedResult() + { + var telescopeRaResult = "HH:MM:SS"; + var hmsResult = 1.2; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GR#")).Returns(telescopeRaResult); + _utilMock.Setup(x => x.HMSToHours(telescopeRaResult)).Returns(hmsResult); + + var result = _telescope.RightAscension; + + _sharedResourcesWrapperMock.Verify( x => x.SendString(":GR#"), Times.Once); + _utilMock.Verify( x => x.HMSToHours(telescopeRaResult), Times.Once); + + Assert.That(result,Is.EqualTo(hmsResult)); + } + + [Test] + public void RightAscensionRate_Get_ThenReturns0() + { + var result = _telescope.RightAscensionRate; + + Assert.That(result, Is.EqualTo(0)); + } + + [Test] + public void RightAscensionRate_Set_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.RightAscensionRate = 1; }); + + Assert.That(excpetion.Property, Is.EqualTo("RightAscensionRate")); + Assert.That(excpetion.AccessorSet, Is.True); + } + + [Test] + public void SetPark_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.SetPark(); }); + + Assert.That(excpetion.Method, Is.EqualTo("SetPark")); + } + + [Test] + public void SideOfPier_Get_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.SideOfPier; }); + + Assert.That(excpetion.Property, Is.EqualTo("SideOfPier")); + Assert.That(excpetion.AccessorSet, Is.False); + } + + [Test] + public void SideOfPier_Set_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.SideOfPier = 0; }); + + Assert.That(excpetion.Property, Is.EqualTo("SideOfPier")); + Assert.That(excpetion.AccessorSet, Is.True); + } + + [Test] + public void SiteElevation_Get_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.SiteElevation; }); + + Assert.That(excpetion.Property, Is.EqualTo("SiteElevation")); + Assert.That(excpetion.AccessorSet, Is.False); + } + + [Test] + public void SiteElevation_Set_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.SiteElevation = 0; }); + + Assert.That(excpetion.Property, Is.EqualTo("SiteElevation")); + Assert.That(excpetion.AccessorSet, Is.True); + } + + [Test] + public void SlewSettleTime_Get_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { var result = _telescope.SlewSettleTime; }); + + Assert.That(excpetion.Property, Is.EqualTo("SlewSettleTime")); + Assert.That(excpetion.AccessorSet, Is.False); + } + + [Test] + public void SlewSettleTime_Set_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.SlewSettleTime = 0; }); + + Assert.That(excpetion.Property, Is.EqualTo("SlewSettleTime")); + Assert.That(excpetion.AccessorSet, Is.True); + } + + [Test] + public void Unpark_ThenThrowsException() + { + var excpetion = Assert.Throws(() => { _telescope.Unpark(); }); + + Assert.That(excpetion.Method, Is.EqualTo("Unpark")); + } + + [Test] + public void SiteLatitude_Get_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _telescope.SiteLatitude; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SiteLatitude Get")); + } + + [Test] + public void SiteLatitude_Get_WhenConnected_ThenRetrievesAndReturnsExpectedValue() + { + var siteLatitudeString = "testLatString"; + var siteLatitudeValue = 123.45; + + ConnectTelescope(); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":Gt#")).Returns(siteLatitudeString); + _utilMock.Setup(x => x.DMSToDegrees(siteLatitudeString)).Returns(siteLatitudeValue); + + var result = _telescope.SiteLatitude; + + _sharedResourcesWrapperMock.Verify( x => x.SendString(":Gt#"), Times.Once); + + Assert.That(result,Is.EqualTo(siteLatitudeValue)); + } + + [Test] + public void SiteLatitude_Set_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.SiteLatitude = 123.45; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SiteLatitude Set")); + } + + [Test] + public void SiteLatitude_Set_WhenConnectedAndLatitudeIsGreaterThan90_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.SiteLatitude = 90.01; }); + Assert.That(exception.Message, Is.EqualTo("Latitude cannot be greater than 90 degrees.")); + } + + [Test] + public void SiteLatitude_Set_WhenConnectedAndLatitudeIsLessThanNegative90_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.SiteLatitude = -90.01; }); + Assert.That(exception.Message, Is.EqualTo("Latitude cannot be less than -90 degrees.")); + } + + [TestCase(-10.5)] + [TestCase(20.75)] + public void SiteLatitude_Set_WhenValueSetAndTelescopRejects_ThenExceptionThrown(double siteLatitude) + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(It.IsAny())).Returns("0"); + + var exception = Assert.Throws(() => { _telescope.SiteLatitude = siteLatitude; }); + + Assert.That(exception.Message, Is.EqualTo("Failed to set site latitude.")); + } + + [TestCase(-10.5, ":St-10*30#")] + [TestCase(20.75, ":St+20*45#")] + public void SiteLatitude_Set_WhenValidValues_ThenValueSentToTelescope(double siteLatitude, string expectedCommand) + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(expectedCommand)).Returns("1"); + + _telescope.SiteLatitude = siteLatitude; + + _sharedResourcesWrapperMock.Verify(x => x.SendChar(expectedCommand), Times.Once); + } + + [Test] + public void SiteLongitude_Get_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _telescope.SiteLongitude; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SiteLongitude Get")); + } + + + //todo figure out if this is right. don't feel right to me + [TestCase("5", 5, -5)] + [TestCase("-5", -5, 5)] + [TestCase("185", 185, 175)] + [TestCase("350", 350, 10)] + public void SiteLongitude_Get_WhenConnected_ThenRetrivesAndReturnsExpectedValue(string telescopelongitudeString, double telescopeLongitudeValue, double expectedResult) + { + var telescopeLongitude = "testLongitude"; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":Gg#")).Returns(telescopeLongitude); + _utilMock.Setup(x => x.DMSToDegrees(telescopeLongitude)).Returns(telescopeLongitudeValue); + + var result = _telescope.SiteLongitude; + + Assert.That(result, Is.EqualTo(expectedResult)); + } + + [Test] + public void SiteLongitude_Set_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.SiteLongitude = 123.45; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SiteLongitude Set")); + } + + [Test] + public void SiteLongitude_Set_WhenConnectedAndGreaterThan180_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.SiteLongitude = 180.1; }); + Assert.That(exception.Message, Is.EqualTo("Longitude cannot be greater than 180 degrees.")); + } + + [Test] + public void SiteLongitude_Set_WhenConnectedAndLessThanNegative180_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.SiteLongitude = -180.1; }); + Assert.That(exception.Message, Is.EqualTo("Longitude cannot be lower than -180 degrees.")); + } + + [Test] + public void SiteLongitude_Set_WhenConnectedAndTelescopeFails_ThenThrowsException() + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(It.IsAny())).Returns("0"); + + var exception = Assert.Throws(() => { _telescope.SiteLongitude = 10; }); + Assert.That(exception.Message, Is.EqualTo("Failed to set site longitude.")); + } + + [TestCase(10, ":Sg350*00#")] + public void SiteLongitude_Set_WhenConnectedAndTelescopeFails_ThenThrowsException(double longitude, string expectedCommand) + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(expectedCommand)).Returns("1"); + + _telescope.SiteLongitude = longitude; + + _sharedResourcesWrapperMock.Verify(x => x.SendChar(expectedCommand), Times.Once); + } + + [Test] + public void SyncToAltAz_WhenConnected_ThenSendsExpectedMessage() + { + string expectedMessage = "test blind Message"; + + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.SyncToAltAz(0,0); }); + + Assert.That(exception.Message, Is.EqualTo("Method SyncToAltAz is not implemented in this driver.")); + } + + [Test] + public void SyncToTarget_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.SyncToTarget(); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SyncToTarget")); + } + + [Test] + public void SyncToTarget_WhenSyncToTargetFails_ThenThrowsException() + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":CM#")).Returns(string.Empty); + + var exception = Assert.Throws(() => { _telescope.SyncToTarget(); } ); + + Assert.That(exception.Message, Is.EqualTo("Unable to perform sync")); + _sharedResourcesWrapperMock.Verify(x => x.SendString(":CM#"), Times.Once); + } + + [Test] + public void SyncToTarget_WhenSyncToTargetWorks_ThennoExceptionThrown() + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":CM#")).Returns(" M31 EX GAL MAG 3.5 SZ178.0'#"); + + Assert.DoesNotThrow(() => { _telescope.SyncToTarget(); }); + + _sharedResourcesWrapperMock.Verify(x => x.SendString(":CM#"), Times.Once); + } + + [Test] + public void TargetDeclination_Set_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.TargetDeclination = 0; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: TargetDeclination Set")); + } + + [Test] + public void TargetDeclination_Set_WhenValueTooHigh_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.TargetDeclination = 90.1; }); + Assert.That(exception.Message, Is.EqualTo("Declination cannot be greater than 90.")); + } + + [Test] + public void TargetDeclination_Set_WhenValueTooLow_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.TargetDeclination = -90.1; }); + Assert.That(exception.Message, Is.EqualTo("Declination cannot be less than -90.")); + } + + [Test] + public void TargetDeclination_Set_WhenTelescopeReportsInvalidDec_ThenThrowsException() + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(It.IsAny())).Returns("0"); + + var exception = Assert.Throws(() => { _telescope.TargetDeclination = 50; }); + Assert.That(exception.Message, Is.EqualTo("Target declination invalid")); + } + + [TestCase(-30.5, "-30*30:00", ":Sd-30*30:00#")] + [TestCase(30.5, "30*30:00", ":Sd+30*30:00#")] + [TestCase(-75.25, "-75*15:00", ":Sd-75*15:00#")] + [TestCase(50, "50*00:00", ":Sd+50*00:00#")] + public void TargetDeclination_Set_WhenValueOK_ThenSetsNewTargetDeclination( double declination,string decstring, string commandString) + { + ConnectTelescope(); + + _utilMock.Setup(x => x.DegreesToDMS(declination, "*", ":", ":", 2)).Returns(decstring); + _sharedResourcesWrapperMock.Setup(x => x.SendChar(commandString)).Returns("1"); + + _telescope.TargetDeclination = declination; + + _sharedResourcesWrapperMock.Verify(x => x.SendChar(commandString),Times.Once); + } + + [Test] + public void TargetDeclination_Get_WhenTargetNotSet_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { var result = _telescope.TargetDeclination; }); + Assert.That(exception.Message, Is.EqualTo("Target not set")); + } + + [TestCase(50, "50*00:00", ":Sd+50*00:00#")] + public void TargetDeclination_Get_WhenValueOK_ThenSetsNewTargetDeclination(double declination, string decstring, string commandString) + { + ConnectTelescope(); + + _utilMock.Setup(x => x.DegreesToDMS(declination, "*", ":", ":", 2)).Returns(decstring); + _sharedResourcesWrapperMock.Setup(x => x.SendChar(commandString)).Returns("1"); + + _telescope.TargetDeclination = declination; + + var result = _telescope.TargetDeclination; + + Assert.That(result, Is.EqualTo(declination)); + } + + [Test] + public void TargetRightAscension_Set_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.TargetRightAscension = 0; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: TargetRightAscension Set")); + } + + [Test] + public void TargetRightAscension_Set_WhenValueTooHigh_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.TargetRightAscension = 24; }); + Assert.That(exception.Message, Is.EqualTo("Right ascension value cannot be greater than 23:59:59")); + } + + [Test] + public void TargetRightAscension_Set_WhenValueTooLow_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.TargetRightAscension = -0.1; }); + Assert.That(exception.Message, Is.EqualTo("Right ascension value cannot be below 0")); + } + + [Test] + public void TargetRightAscension_Set_WhenTelescopeReportsInvalidRA_ThenThrowsException() + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(It.IsAny())).Returns("0"); + + var exception = Assert.Throws(() => { _telescope.TargetRightAscension = 1; }); + Assert.That(exception.Message, Is.EqualTo("Failed to set TargetRightAscension.")); + } + + [TestCase(5.5, "05:30:00", ":Sr05:30:00#")] + [TestCase(10, "10:00:00", ":Sr10:00:00#")] + public void TargetRightAscension_Set_WhenValueOK_ThenSetsNewTargetDeclination(double rightAscension, string hms, string commandString) + { + ConnectTelescope(); + + _utilMock.Setup(x => x.HoursToHMS(rightAscension, ":", ":", ":", 2)).Returns(hms); + _sharedResourcesWrapperMock.Setup(x => x.SendChar(commandString)).Returns("1"); + + _telescope.TargetRightAscension = rightAscension; + + _sharedResourcesWrapperMock.Verify(x => x.SendChar(commandString), Times.Once); + } + + [Test] + public void TargetRightAscension_Get_WhenTargetNotSet_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { var result = _telescope.TargetRightAscension; }); + Assert.That(exception.Message, Is.EqualTo("Target not set")); + } + + [TestCase(15, "15:00:00", ":Sr15:00:00#")] + public void TargetRightAscension_Get_WhenValueOK_ThenSetsNewTargetDeclination(double rightAscension, string hms, string commandString) + { + ConnectTelescope(); + + _utilMock.Setup(x => x.HoursToHMS(rightAscension, ":", ":", ":", 2)).Returns(hms); + _sharedResourcesWrapperMock.Setup(x => x.SendChar(commandString)).Returns("1"); + + _telescope.TargetRightAscension = rightAscension; + + var result = _telescope.TargetRightAscension; + + Assert.That(result, Is.EqualTo(rightAscension)); + } + + [Test] + public void Tracking_Get_WhenDefault_ThenIsTrue() + { + Assert.That(_telescope.Tracking, Is.True); + } + + [TestCase(true)] + [TestCase(false)] + public void Tracking_SetAndGet_WhenValueSet_ThenCanGetNewValue(bool tracking) + { + _telescope.Tracking = tracking; + + Assert.That(_telescope.Tracking, Is.EqualTo( tracking)); + } + + [Test] + public void TrackingRate_Set_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.TrackingRate = DriveRates.driveSidereal; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: TrackingRate Set")); + } + + [TestCase(DriveRates.driveSidereal, ":TQ#")] + [TestCase(DriveRates.driveLunar, ":TL#")] + public void TrackingRate_Set_WhenConnected_ThenSendsCommandToTelescope(DriveRates rate, string commandString) + { + ConnectTelescope(); + + _telescope.TrackingRate = rate; + + _sharedResourcesWrapperMock.Verify( x => x.SendBlind(commandString), Times.Once); + } + + [Test] + public void TrackingRate_Set_WhenUnSupportedRateSet_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws( () => { _telescope.TrackingRate = DriveRates.driveKing; }); + + Assert.That(exception.Message, Is.EqualTo("Exception of type 'System.ArgumentOutOfRangeException' was thrown.\r\nParameter name: value\r\nActual value was driveKing.")); + } + + [Test] + public void TrackingRage_Get_WhenReadongDefaultValue_ThenAssumesSidereal() + { + ConnectTelescope(); + + var result = _telescope.TrackingRate; + + Assert.That(result, Is.EqualTo(DriveRates.driveSidereal)); + } + + [TestCase(DriveRates.driveSidereal)] + [TestCase(DriveRates.driveLunar)] + public void TrackingRate_Get_WhenConnected_ThenSendsCommandToTelescope(DriveRates rate) + { + ConnectTelescope(); + + _telescope.TrackingRate = rate; + + var result = _telescope.TrackingRate; + + Assert.That(result, Is.EqualTo(rate)); + } + + [Test] + public void TrackingRates_Get_ReturnsExpectedType() + { + var result = _telescope.TrackingRates; + + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.AssignableTo()); + } + + [Test] + public void UTCDate_Get_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _telescope.UTCDate; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: UTCDate Get")); + } + + [TestCase("10/15/20", "20:15:10", "-1.0", 2020, 10, 15, 19, 15, 10)] + [TestCase("12/03/15", "21:30:45", "+0.0", 2015, 12, 3, 21, 30, 45)] + public void UTCDate_Get_WhenConnected_ThenReturnsUTCDateTime(string telescopeDate, string telescopeTime, + string telescopeUtcCorrection, int year, int month, int day, int hour, int min, int second) + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GC#")).Returns(telescopeDate); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GL#")).Returns(telescopeTime); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GG#")).Returns(telescopeUtcCorrection); + + var result = _telescope.UTCDate; + + Assert.That(result, Is.Not.Null); + Assert.That(result, Is.AssignableTo()); + Assert.That(result.Kind, Is.EqualTo(DateTimeKind.Utc)); + Assert.That(result.Year, Is.EqualTo(year)); + Assert.That(result.Month, Is.EqualTo(month)); + Assert.That(result.Day, Is.EqualTo(day)); + Assert.That(result.Hour, Is.EqualTo(hour)); + Assert.That(result.Minute, Is.EqualTo(min)); + Assert.That(result.Second, Is.EqualTo(second)); + } + + [Test] + public void UTCDate_Set_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.UTCDate = new DateTime(2010,10,15,16,42,32, DateTimeKind.Utc); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: UTCDate Set")); + } + + [TestCase("10/15/20", "20:15:10", "-1.0", 2020, 10, 15, 19, 15, 10)] + [TestCase("12/03/15", "21:30:45", "+0.0", 2015, 12, 3, 21, 30, 45)] + public void UTCDate_Set_WhenFailsToSetTelescopeTime_ThenThrowsException(string telescopeDate, string telescopeTime, string telescopeUtcCorrection, int year, int month, int day, int hour, int min, int second) + { + double utcOffsetHours = double.Parse(telescopeUtcCorrection); + TimeSpan utcCorrection = TimeSpan.FromHours(utcOffsetHours); + + var newDate = new DateTime(year, month, day, hour, min, second, DateTimeKind.Local) + utcCorrection; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GG#")).Returns(telescopeUtcCorrection); + _sharedResourcesWrapperMock.Setup(x => x.SendChar($":SL{telescopeTime}#")).Returns("0"); + + var exception = Assert.Throws(() => { _telescope.UTCDate = newDate; } ); + + Assert.That(exception.Message, Is.EqualTo("Failed to set local time")); + } + + [TestCase("10/15/20", "20:15:10", "-1.0", 2020, 10, 15, 20, 15, 10)] + [TestCase("12/03/15", "21:30:45", "+0.0", 2015, 12, 3, 21, 30, 45)] + public void UTCDate_Set_WhenFailsToSetTelescopeDate_ThenThrowsException(string telescopeDate, string telescopeTime, string telescopeUtcCorrection, int year, int month, int day, int hour, int min, int second) + { + double utcOffsetHours = double.Parse(telescopeUtcCorrection); + TimeSpan utcCorrection = TimeSpan.FromHours(utcOffsetHours); + + var newDate = new DateTime(year, month, day, hour, min, second, DateTimeKind.Local) + utcCorrection; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GG#")).Returns(telescopeUtcCorrection); + _sharedResourcesWrapperMock.Setup(x => x.SendChar($":SL{telescopeTime}#")).Returns("1"); + _sharedResourcesWrapperMock.Setup(x => x.SendChar($":SC{newDate:MM/dd/yy}#")).Returns("0"); + + var exception = Assert.Throws(() => { _telescope.UTCDate = newDate; }); + + Assert.That(exception.Message, Is.EqualTo("Failed to set local date")); + } + + [TestCase("10/15/20", "20:15:10", "-1.0", 2020, 10, 15, 20, 15, 10)] + [TestCase("12/03/15", "21:30:45", "+0.0", 2015, 12, 3, 21, 30, 45)] + public void UTCDate_Set_WhenSucceeds_ThenReadsTwoStringsFromTelescope(string telescopeDate, + string telescopeTime, string telescopeUtcCorrection, int year, int month, int day, int hour, int min, + int second) + { + double utcOffsetHours = double.Parse(telescopeUtcCorrection); + TimeSpan utcCorrection = TimeSpan.FromHours(utcOffsetHours); + + var newDate = new DateTime(year, month, day, hour, min, second, DateTimeKind.Local) + utcCorrection; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GG#")).Returns(telescopeUtcCorrection); + _sharedResourcesWrapperMock.Setup(x => x.SendChar($":SL{telescopeTime}#")).Returns("1"); + _sharedResourcesWrapperMock.Setup(x => x.SendChar($":SC{telescopeDate}#")).Returns("1"); + + _telescope.UTCDate = newDate; + + _sharedResourcesWrapperMock.Verify(x => x.ReadTerminated(), Times.Exactly(2)); + } + + [Test] + public void SyncToCoordinates_WhenNotConnected_ThenThrowsException() + { + double rightAscension = 5.5; + string hms = "05:30:00"; + + double declination = -30.5; + string dec = "-30*30:00"; + + ConnectTelescope(); + + _utilMock.Setup(x => x.HoursToHMS(rightAscension, ":", ":", ":", 2)).Returns(hms); + _sharedResourcesWrapperMock.Setup(x => x.SendChar($":Sr{hms}#")).Returns("1"); + + _utilMock.Setup(x => x.DegreesToDMS(declination, "*", ":", ":", 2)).Returns(dec); + _sharedResourcesWrapperMock.Setup(x => x.SendChar($":Sd{dec}#")).Returns("1"); + + _telescope.SyncToCoordinates(rightAscension, declination); + + _sharedResourcesWrapperMock.Verify( x => x.SendString(":CM#"), Times.Once); + Assert.That(_telescope.TargetRightAscension, Is.EqualTo(rightAscension)); + Assert.That(_telescope.TargetDeclination, Is.EqualTo(declination)); + } + + [Test] + public void Slewing_WhenNotConnected_ThenReturnsFalse() + { + var result = _telescope.Slewing; + + Assert.That(result, Is.False); + + _sharedResourcesWrapperMock.Verify(x => x.SendString(":D#"), Times.Never); + } + + [Test] + public void Slewing_WhenConnectedAndTelescopeFails_ThenReturnsFalse() + { + ConnectTelescope(); + + var result = _telescope.Slewing; + + Assert.That(result, Is.False); + + _sharedResourcesWrapperMock.Verify(x => x.SendString(":D#"), Times.Once); + } + + [Test] + public void Slewing_WhenTelescopeIsSlewing_ThenReturnsTrue() + { + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":D#")).Returns("|"); + + var result = _telescope.Slewing; + + Assert.That(result, Is.True); + + _sharedResourcesWrapperMock.Verify(x => x.SendString(":D#"),Times.Once); + } + + [TestCase(1, TelescopeAxes.axisPrimary)] + [TestCase(-1, TelescopeAxes.axisPrimary)] + [TestCase(1, TelescopeAxes.axisSecondary)] + [TestCase(-1, TelescopeAxes.axisSecondary)] + public void Slewing_WhenTelescopeIsMoving_ThenDoesNotSendCommandAndReturnsTrue(int rate, TelescopeAxes axis) + { + ConnectTelescope(); + + _telescope.MoveAxis(axis, rate); + + var result = _telescope.Slewing; + + Assert.That(result, Is.True); + _sharedResourcesWrapperMock.Verify(x => x.SendString(":D#"), Times.Never); + } + + + [Test] + public void SlewToTargetAsync_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.SlewToTargetAsync(); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SlewToTargetAsync")); + } + + [Test] + public void SlewToTargetAsync_WhenTargetDeclinationNotSet_ThenThrowsException() + { + ConnectTelescope(); + + _telescope.TargetRightAscension = 1; + + var exception = Assert.Throws(() => { _telescope.SlewToTargetAsync(); }); + Assert.That(exception.Message, Is.EqualTo("Target not set")); + } + + [Test] + public void SlewToTargetAsync_WhenTargetRightAscensionNotSet_ThenThrowsException() + { + ConnectTelescope(); + + _telescope.TargetDeclination = 1; + + var exception = Assert.Throws(() => { _telescope.SlewToTargetAsync(); }); + Assert.That(exception.Message, Is.EqualTo("Target not set")); + } + + [Test] + public void SlewToTargetAsync_WhenTargetSet_ThenAttemptsSlew() + { + ConnectTelescope(); + + _telescope.TargetRightAscension = 2; + _telescope.TargetDeclination = 1; + + var exception = Assert.Throws(() => { _telescope.SlewToTargetAsync(); }); + Assert.That(exception.Message, Is.EqualTo("This error should not happen")); + } + + [Test] + public void SlewToTargetAsync_WhenTargetSetAndSlewIsPossible_ThenAttemptsSlew() + { + ConnectTelescope(); + + _telescope.TargetRightAscension = 2; + _telescope.TargetDeclination = 1; + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(":MS#")).Returns("0"); + + _telescope.SlewToTargetAsync(); + + _sharedResourcesWrapperMock.Verify(x => x.SendChar(":MS#"), Times.Once); + } + + [Test] + public void SlewToTargetAsync_WhenTargetBelowHorizon_ThenThrowsException() + { + ConnectTelescope(); + + _telescope.TargetRightAscension = 2; + _telescope.TargetDeclination = 1; + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(":MS#")).Returns("1"); + + _sharedResourcesWrapperMock.Setup(x => x.ReadTerminated()).Returns("Below horizon"); + + var exception = Assert.Throws(() => { _telescope.SlewToTargetAsync(); }); + Assert.That(exception.Message, Is.EqualTo("Below horizon")); + } + + [Test] + public void SlewToTargetAsync_WhenTargetBelowElevation_ThenThrowsException() + { + ConnectTelescope(); + + _telescope.TargetRightAscension = 2; + _telescope.TargetDeclination = 1; + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(":MS#")).Returns("2"); + + _sharedResourcesWrapperMock.Setup(x => x.ReadTerminated()).Returns("Above below elevation"); + + var exception = Assert.Throws(() => { _telescope.SlewToTargetAsync(); }); + Assert.That(exception.Message, Is.EqualTo("Above below elevation")); + } + + [Test] + public void SlewToTarget_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.SlewToTarget(); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SlewToTarget")); + } + + [Test] + public void SlewToTarget_WhenSlewing_ThenWaitsForTheSlewToComplete() + { + ConnectTelescope(); + + _telescope.TargetRightAscension = 2; + _telescope.TargetDeclination = 1; + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(":MS#")).Returns("0"); + + var slewCounter = 0; + var iterations = 10; + _sharedResourcesWrapperMock.Setup(x => x.SendString(":D#")).Returns(() => + { + slewCounter++; + if (slewCounter <= iterations) + return "|"; + else + return ""; + }); + + _telescope.SlewToTarget(); + + _utilMock.Verify( x => x.WaitForMilliseconds(It.IsAny()), Times.Exactly(iterations)); + } + + [Test] + public void SlewToCoordinatesAsync_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.SlewToCoordinatesAsync(0,0); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SlewToCoordinatesAsync")); + } + + [Test] + public void SlewToCoordinatesAsync_WhenCalled_ThenSetsTargetAndSlews() + { + var rightAscension = 1; + var declination = 2; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(":MS#")).Returns("0"); + + //var slewCounter = 0; + //var iterations = 10; + //_sharedResourcesWrapperMock.Setup(x => x.SendString(":D#")).Returns(() => + //{ + // slewCounter++; + // if (slewCounter <= iterations) + // return "|"; + // else + // return ""; + //}); + + _telescope.SlewToCoordinatesAsync(rightAscension, declination); + + //_utilMock.Verify(x => x.WaitForMilliseconds(It.IsAny()), Times.Exactly(iterations)); + Assert.That(_telescope.TargetRightAscension, Is.EqualTo(rightAscension)); + Assert.That(_telescope.TargetDeclination, Is.EqualTo(declination)); + _sharedResourcesWrapperMock.Verify( x => x.SendChar(":MS#"), Times.Once); + } + + [Test] + public void SlewToCoordinates_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.SlewToCoordinates(0, 0); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SlewToCoordinates")); + } + + [Test] + public void SlewToCoordinates_WhenCalled_ThenSetsTargetAndSlews() + { + var rightAscension = 1; + var declination = 2; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(":MS#")).Returns("0"); + + var slewCounter = 0; + var iterations = 10; + _sharedResourcesWrapperMock.Setup(x => x.SendString(":D#")).Returns(() => + { + slewCounter++; + if (slewCounter <= iterations) + return "|"; + else + return ""; + }); + + _telescope.SlewToCoordinates(rightAscension, declination); + Assert.That(_telescope.TargetRightAscension, Is.EqualTo(rightAscension)); + Assert.That(_telescope.TargetDeclination, Is.EqualTo(declination)); + _sharedResourcesWrapperMock.Verify(x => x.SendChar(":MS#"), Times.Once); + + _utilMock.Verify(x => x.WaitForMilliseconds(It.IsAny()), Times.Exactly(iterations)); + } + + [Test] + public void SlewToAltAzAsync_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.SlewToAltAzAsync(0, 0); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SlewToAltAzAsync")); + } + + [Test] + public void SlewToAltAzAsync_WhenAltitudeGreaterThan90_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.SlewToAltAzAsync(0, 90.1); }); + Assert.That(exception.Message, Is.EqualTo("Altitude cannot be greater than 90.")); + } + + [Test] + public void SlewToAltAzAsync_WhenAltitudeLowerThan0_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.SlewToAltAzAsync(0, -0.1); }); + Assert.That(exception.Message, Is.EqualTo("Altitide cannot be less than 0.")); + } + + [Test] + public void SlewToAltAzAsync_WhenAzimuth360OrHigher_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.SlewToAltAzAsync(360, 0); }); + Assert.That(exception.Message, Is.EqualTo("Azimuth cannot be 360 or higher.")); + } + + [Test] + public void SlewToAltAzAsync_WhenAzimuthLowerThan0_ThenThrowsException() + { + ConnectTelescope(); + + var exception = Assert.Throws(() => { _telescope.SlewToAltAzAsync(-0.1, 0); }); + Assert.That(exception.Message, Is.EqualTo("Azimuth cannot be less than 0.")); + } + + [Test] + public void SlewToAltAzAsync_WhenAltAndAzValid_ThenConvertsToRADec() + { + var altitude = 30; + var azimuth = 45; + var rightAscension = 20; + var declination = 10; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GC#")).Returns("10/15/20"); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GL#")).Returns("20:15:10"); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GG#")).Returns("-1.0"); + + _astroMathsMock + .Setup(x => x.ConvertHozToEq(It.IsAny(), It.IsAny(), It.IsAny(), + It.IsAny())).Returns(new EquatorialCoordinates(){ Declination = declination, RightAscension = rightAscension }); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(":MS#")).Returns("0"); + + _telescope.SlewToAltAzAsync(azimuth, altitude); + + Assert.That(_telescope.TargetRightAscension, Is.EqualTo(rightAscension)); + Assert.That(_telescope.TargetDeclination, Is.EqualTo(declination)); + _sharedResourcesWrapperMock.Verify(x => x.SendChar(":MS#"), Times.Once); + } + + [Test] + public void SlewToAltAz_WhenAzimuthLowerThan0_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.SlewToAltAz(0, 0); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: SlewToAltAz")); + } + + [Test] + public void SlewToAltAz_WhenCalled_ThenSetsTargetAndSlews() + { + var rightAscension = 10; + var declination = 20; + var azimuth = 30; + var altitude = 40; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GC#")).Returns("10/15/20"); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GL#")).Returns("20:15:10"); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GG#")).Returns("-1.0"); + + _astroMathsMock + .Setup(x => x.ConvertHozToEq(It.IsAny(), It.IsAny(), It.IsAny(), + It.IsAny())).Returns(new EquatorialCoordinates() { Declination = declination, RightAscension = rightAscension }); + + _sharedResourcesWrapperMock.Setup(x => x.SendChar(":MS#")).Returns("0"); + + var slewCounter = 0; + var iterations = 10; + _sharedResourcesWrapperMock.Setup(x => x.SendString(":D#")).Returns(() => + { + slewCounter++; + if (slewCounter <= iterations) + return "|"; + else + return ""; + }); + + _telescope.SlewToAltAz( azimuth, altitude); + + Assert.That(_telescope.TargetRightAscension, Is.EqualTo(rightAscension)); + Assert.That(_telescope.TargetDeclination, Is.EqualTo(declination)); + _sharedResourcesWrapperMock.Verify(x => x.SendChar(":MS#"), Times.Once); + _utilMock.Verify(x => x.WaitForMilliseconds(It.IsAny()), Times.Exactly(iterations)); + } + + [Test] + public void Azimuth_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _telescope.Azimuth; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: Azimuth Get")); + } + + [Test] + public void Azimuth_WhenConnected_ThenReturnsTelescopeAzumith() + { + var expectedAzimuth = 200; + + var telescopeLongitude = "350"; + var telescopeLongitudeValue = 350; + + var telescopeLatitude = "HH:MM:SS"; + var telescopeLatitudeValue = 1.2; + + var mockHourAngle = 3; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GC#")).Returns("10/15/20"); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GL#")).Returns("20:15:10"); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GG#")).Returns("-1.0"); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":Gg#")).Returns(telescopeLongitude); + _utilMock.Setup(x => x.DMSToDegrees(telescopeLongitude)).Returns(telescopeLongitudeValue); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GR#")).Returns(telescopeLatitude); + _utilMock.Setup(x => x.HMSToHours(telescopeLatitude)).Returns(telescopeLatitudeValue); + + _astroMathsMock.Setup(x => x.RightAscensionToHourAngle(It.IsAny(), It.IsAny(), It.IsAny())).Returns(mockHourAngle); + + _astroMathsMock.Setup(x => x.ConvertEqToHoz(mockHourAngle, It.IsAny(), It.IsAny())).Returns( new HorizonCoordinates{ Altitude = 45, Azimuth = expectedAzimuth }); + + var result = _telescope.Azimuth; + + Assert.That(result,Is.EqualTo(expectedAzimuth)); + } + + [Test] + public void Altitude_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { var result = _telescope.Altitude; }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: Altitude Get")); + } + + [Test] + public void Altitude_WhenConnected_ThenReturnsTelescopeAltitude() + { + var expectedAltitude = 45; + + var telescopeLongitude = "350"; + var telescopeLongitudeValue = 350; + + var telescopeLatitude = "HH:MM:SS"; + var telescopeLatitudeValue = 1.2; + + var mockHourAngle = 3; + + ConnectTelescope(); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GC#")).Returns("10/15/20"); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GL#")).Returns("20:15:10"); + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GG#")).Returns("-1.0"); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":Gg#")).Returns(telescopeLongitude); + _utilMock.Setup(x => x.DMSToDegrees(telescopeLongitude)).Returns(telescopeLongitudeValue); + + _sharedResourcesWrapperMock.Setup(x => x.SendString(":GR#")).Returns(telescopeLatitude); + _utilMock.Setup(x => x.HMSToHours(telescopeLatitude)).Returns(telescopeLatitudeValue); + + _astroMathsMock.Setup(x => x.RightAscensionToHourAngle(It.IsAny(), It.IsAny(), It.IsAny())).Returns(mockHourAngle); + + _astroMathsMock.Setup(x => x.ConvertEqToHoz(mockHourAngle, It.IsAny(), It.IsAny())).Returns(new HorizonCoordinates { Altitude = expectedAltitude, Azimuth = 200 }); + + var result = _telescope.Altitude; + + Assert.That(result, Is.EqualTo(expectedAltitude)); + } + + [Test] + public void AbortSlew_WhenNotConnected_ThenThrowsException() + { + var exception = Assert.Throws(() => { _telescope.AbortSlew(); }); + Assert.That(exception.Message, Is.EqualTo("Not connected to telescope when trying to execute: AbortSlew")); + } + + [Test] + public void AbortSlew_WhenConnected_ThenSendsStopSlewingToTelescope() + { + ConnectTelescope(); + + _telescope.AbortSlew(); + + _sharedResourcesWrapperMock.Verify( x => x.SendBlind(":Q#"),Times.Once); + + var isSloSlewing = _telescope.Slewing; + + Assert.That(isSloSlewing, Is.False); + _sharedResourcesWrapperMock.Verify( x => x.SendString(":D#"), Times.Once); + } + } +} +; \ No newline at end of file diff --git a/Meade.net.Telescope.UnitTests/app.config b/Meade.net.Telescope.UnitTests/app.config new file mode 100644 index 0000000..312e994 --- /dev/null +++ b/Meade.net.Telescope.UnitTests/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Meade.net.Telescope.UnitTests/packages.config b/Meade.net.Telescope.UnitTests/packages.config new file mode 100644 index 0000000..b360f81 --- /dev/null +++ b/Meade.net.Telescope.UnitTests/packages.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/Meade.net.Telescope/AstroMaths/AltitudeData.cs b/Meade.net.Telescope/AstroMaths/AltitudeData.cs new file mode 100644 index 0000000..6ca2890 --- /dev/null +++ b/Meade.net.Telescope/AstroMaths/AltitudeData.cs @@ -0,0 +1,12 @@ +using System; + +namespace ASCOM.Meade.net.AstroMaths +{ + public class AltitudeData + { + public DateTime UtcDateTime { get; set; } + public double SiteLatitude { get; set; } + public double SiteLongitude { get; set; } + public EquatorialCoordinates EquatorialCoordinates { get; set; } + } +} \ No newline at end of file diff --git a/Meade.net.Telescope/AstroMaths.cs b/Meade.net.Telescope/AstroMaths/AstroMaths.cs similarity index 84% rename from Meade.net.Telescope/AstroMaths.cs rename to Meade.net.Telescope/AstroMaths/AstroMaths.cs index 7123eaa..17e168b 100644 --- a/Meade.net.Telescope/AstroMaths.cs +++ b/Meade.net.Telescope/AstroMaths/AstroMaths.cs @@ -1,38 +1,17 @@ using System; using ASCOM.Utilities; -namespace ASCOM.Meade.net +namespace ASCOM.Meade.net.AstroMaths { - public class EquatorialCoordinates - { - public double RightAscension { get; set; } - public double Declination { get; set; } - } - - public class HorizonCoordinates - { - public double Altitude { get; set; } - public double Azimuth { get; set; } - } - - - public class AltitudeData - { - public DateTime UtcDateTime { get; set; } - public double SiteLatitude { get; set; } - public double SiteLongitude { get; set; } - public EquatorialCoordinates equatorialCoordinates { get; set; } - } - - public class AstroMaths + public class AstroMaths : IAstroMaths { //returns the decimal hour angle for given right ascension on a given datetime for a given logitude. public double RightAscensionToHourAngle(DateTime utcDateTime, double longitude, double rightAscension) { var ut = DateTimeToDecimalHours( utcDateTime); - var gst = UTtoGST( utcDateTime); - var lst = GSTtoLST( gst, longitude); + var gst = UTtoGst( utcDateTime); + var lst = GsTtoLst( gst, longitude); var raHours = rightAscension; var h1 = lst - raHours; var h = h1; @@ -45,8 +24,8 @@ namespace ASCOM.Meade.net public double HourAngleToRightAscension(DateTime utcDateTime, double longitude, double hourAngle ) { - var gst = UTtoGST(utcDateTime); - var lst = GSTtoLST( gst, longitude); + var gst = UTtoGst(utcDateTime); + var lst = GsTtoLst( gst, longitude); var raHours = hourAngle; var h1 = lst - raHours; var h = h1; @@ -150,7 +129,7 @@ namespace ASCOM.Meade.net } //todo convert to extension method - public double UTtoGST(DateTime utcDateTime) + public double UTtoGst(DateTime utcDateTime) { Util util = new Util(); @@ -192,7 +171,7 @@ namespace ASCOM.Meade.net return t1; } - public double GSTtoLST(double gst, double longitude) + public double GsTtoLst(double gst, double longitude) { var l = longitude/ 15; diff --git a/Meade.net.Telescope/AstroMaths/EquatorialCoordinates.cs b/Meade.net.Telescope/AstroMaths/EquatorialCoordinates.cs new file mode 100644 index 0000000..e181e79 --- /dev/null +++ b/Meade.net.Telescope/AstroMaths/EquatorialCoordinates.cs @@ -0,0 +1,8 @@ +namespace ASCOM.Meade.net.AstroMaths +{ + public class EquatorialCoordinates + { + public double RightAscension { get; set; } + public double Declination { get; set; } + } +} \ No newline at end of file diff --git a/Meade.net.Telescope/AstroMaths/HorizonCoordinates.cs b/Meade.net.Telescope/AstroMaths/HorizonCoordinates.cs new file mode 100644 index 0000000..de7eeae --- /dev/null +++ b/Meade.net.Telescope/AstroMaths/HorizonCoordinates.cs @@ -0,0 +1,8 @@ +namespace ASCOM.Meade.net.AstroMaths +{ + public class HorizonCoordinates + { + public double Altitude { get; set; } + public double Azimuth { get; set; } + } +} \ No newline at end of file diff --git a/Meade.net.Telescope/AstroMaths/IAstroMaths.cs b/Meade.net.Telescope/AstroMaths/IAstroMaths.cs new file mode 100644 index 0000000..dfcab3a --- /dev/null +++ b/Meade.net.Telescope/AstroMaths/IAstroMaths.cs @@ -0,0 +1,17 @@ +using System; + +namespace ASCOM.Meade.net.AstroMaths +{ + public interface IAstroMaths + { + double RightAscensionToHourAngle(DateTime utcDateTime, double longitude, double rightAscension); + double HourAngleToRightAscension(DateTime utcDateTime, double longitude, double hourAngle ); + EquatorialCoordinates ConvertHozToEq( DateTime utcDateTime, double latitude, double longitude, HorizonCoordinates altAz); + HorizonCoordinates ConvertEqToHoz(double hourAngle, double latitude, EquatorialCoordinates raDec); + double DegreesToRadians(double degrees); + double RadiansToDegrees(double radians); + double DateTimeToDecimalHours( DateTime utcDateTime); + double UTtoGst(DateTime utcDateTime); + double GsTtoLst(double gst, double longitude); + } +} \ No newline at end of file diff --git a/Meade.net.Telescope/BootstrapAscomProfileStore.ps1 b/Meade.net.Telescope/BootstrapAscomProfileStore.ps1 new file mode 100644 index 0000000..213c64d --- /dev/null +++ b/Meade.net.Telescope/BootstrapAscomProfileStore.ps1 @@ -0,0 +1,36 @@ +<# +This script initializes a bare minimum set of registry entries required for ASCOM.Utilities.Profile to work +without throwing any exceptions. When building on a build server, or on a computer without the ASCOM Platform installed, +it may be useful to execute this script as a build step prior to running any unit tests, or calling any code that relies on +ASCOM.Utilities.Profile. The alternative is to install the ASCOM Platform on the build agent. + +NOTE: This script equires elevated permissions because it creates registry keys in the LocalMachine hive. +#> + +$wow = Test-Path HKLM:\SOFTWARE\Wow6432Node +if ($wow) + { + $root = "HKLM:\SOFTWARE\Wow6432Node" + } +else + { + $root = "HKLM:\SOFTWARE" + } +$ascomRoot = $root + "\ASCOM" + +if (Test-Path $ascomRoot) + { + <# Don't upset an already-existing ASCOM registry #> + exit + } + +<# Create the ASCOM root key and set it's ACL to allow all users read/write access #> +New-Item -Path $root -Name ASCOM –Force +$ascomAcl = Get-Acl $ascomRoot +$aclRule = New-Object System.Security.AccessControl.RegistryAccessRule ("Users","FullControl","Allow") +$ascomAcl.SetAccessRule($aclRule) +$ascomAcl | Set-Acl -Path $ascomRoot + +<# Now create the bare minimum keys required so that ASCOM.Utilities.Profile doesn't crash and burn #> +New-ItemProperty -Path $ascomRoot -Name PlatformVersion -Value "6.1" -PropertyType String –Force +New-ItemProperty -Path $ascomRoot -Name SerTraceFile -Value "C:\SerialTraceAuto.txt" -PropertyType String –Force diff --git a/Meade.net.Telescope/Meade.net.Telescope.csproj b/Meade.net.Telescope/Meade.net.Telescope.csproj index 35f9b0b..cf50efa 100644 --- a/Meade.net.Telescope/Meade.net.Telescope.csproj +++ b/Meade.net.Telescope/Meade.net.Telescope.csproj @@ -68,14 +68,39 @@ x86 - - - - - - - - + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Astrometry.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Attributes.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Cache.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Controls.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DeviceInterfaces.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DriverAccess.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Exceptions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Internal.Extensions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.SettingsProvider.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.Video.dll + @@ -88,7 +113,11 @@ - + + + + + @@ -115,6 +144,8 @@ + + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/Meade.net.Telescope/Meade.net.Telescope.v3.ncrunchproject b/Meade.net.Telescope/Meade.net.Telescope.v3.ncrunchproject new file mode 100644 index 0000000..54c2f06 --- /dev/null +++ b/Meade.net.Telescope/Meade.net.Telescope.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + x86 + + \ No newline at end of file diff --git a/Meade.net.Telescope/Properties/AssemblyInfo.cs b/Meade.net.Telescope/Properties/AssemblyInfo.cs index 5376198..ab1142a 100644 --- a/Meade.net.Telescope/Properties/AssemblyInfo.cs +++ b/Meade.net.Telescope/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -35,5 +34,5 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: // // TODO - Set your driver's version here -[assembly: AssemblyVersion("0.7.0.0")] -[assembly: AssemblyFileVersion("0.7.0.0")] +[assembly: AssemblyVersion("0.0.0.0")] +[assembly: AssemblyFileVersion("0.0.0.0")] diff --git a/Meade.net.Telescope/Rates.cs b/Meade.net.Telescope/Rates.cs index 2230bf7..b3f6f22 100644 --- a/Meade.net.Telescope/Rates.cs +++ b/Meade.net.Telescope/Rates.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; using ASCOM.DeviceInterface; using System.Collections; using System.Threading; @@ -21,10 +17,10 @@ namespace ASCOM.Meade.net [Guid("288838d1-bbf9-4ce0-9ee1-86ecf38b45c9")] [ClassInterface(ClassInterfaceType.None)] [ComVisible(true)] - public class Rate : ASCOM.DeviceInterface.IRate + public class Rate : IRate { - private double maximum = 0; - private double minimum = 0; + private double _maximum = 0; + private double _minimum = 0; // // Default constructor - Internal prevents public creation @@ -32,8 +28,8 @@ namespace ASCOM.Meade.net // internal Rate(double minimum, double maximum) { - this.maximum = maximum; - this.minimum = minimum; + _maximum = maximum; + _minimum = minimum; } #region Implementation of IRate @@ -45,14 +41,14 @@ namespace ASCOM.Meade.net public double Maximum { - get { return this.maximum; } - set { this.maximum = value; } + get => _maximum; + set => _maximum = value; } public double Minimum { - get { return this.minimum; } - set { this.minimum = value; } + get => _minimum; + set => _minimum = value; } #endregion @@ -74,8 +70,8 @@ namespace ASCOM.Meade.net [ComVisible(true)] public class AxisRates : IAxisRates, IEnumerable { - private TelescopeAxes axis; - private readonly Rate[] rates; + private TelescopeAxes _axis; + private readonly Rate[] _rates; // // Constructor - Internal prevents public creation @@ -83,7 +79,7 @@ namespace ASCOM.Meade.net // internal AxisRates(TelescopeAxes axis) { - this.axis = axis; + _axis = axis; // // This collection must hold zero or more Rate objects describing the // rates of motion ranges for the Telescope.MoveAxis() method @@ -100,26 +96,23 @@ namespace ASCOM.Meade.net // TODO Initialize this array with any Primary axis rates that your driver may provide // Example: m_Rates = new Rate[] { new Rate(10.5, 30.2), new Rate(54.0, 43.6) } //this.rates = new Rate[0]; - this.rates = new Rate[] { new Rate(1, 1), new Rate(2, 2), new Rate(3, 3), new Rate(4, 4) }; + _rates = new Rate[] { new Rate(1, 1), new Rate(2, 2), new Rate(3, 3), new Rate(4, 4) }; break; case TelescopeAxes.axisSecondary: // TODO Initialize this array with any Secondary axis rates that your driver may provide //this.rates = new Rate[0]; - this.rates = new Rate[] { new Rate(1, 1), new Rate(2, 2), new Rate(3, 3), new Rate(4, 4) }; + _rates = new Rate[] { new Rate(1, 1), new Rate(2, 2), new Rate(3, 3), new Rate(4, 4) }; break; case TelescopeAxes.axisTertiary: // TODO Initialize this array with any Tertiary axis rates that your driver may provide - this.rates = new Rate[0]; + _rates = new Rate[0]; break; } } #region IAxisRates Members - public int Count - { - get { return this.rates.Length; } - } + public int Count => _rates.Length; public void Dispose() { @@ -128,13 +121,10 @@ namespace ASCOM.Meade.net public IEnumerator GetEnumerator() { - return rates.GetEnumerator(); + return _rates.GetEnumerator(); } - public IRate this[int index] - { - get { return this.rates[index - 1]; } // 1-based - } + public IRate this[int index] => _rates[index - 1]; #endregion } @@ -159,11 +149,11 @@ namespace ASCOM.Meade.net [ComVisible(true)] public class TrackingRates : ITrackingRates, IEnumerable, IEnumerator { - private readonly DriveRates[] trackingRates; + private readonly DriveRates[] _trackingRates; // this is used to make the index thread safe - private readonly ThreadLocal pos = new ThreadLocal(() => { return -1; }); - private static readonly object lockObj = new object(); + private readonly ThreadLocal _pos = new ThreadLocal(() => { return -1; }); + private static readonly object LockObj = new object(); // // Default constructor - Internal prevents public creation @@ -176,20 +166,17 @@ namespace ASCOM.Meade.net // the tracking rates supported by your telescope. The one value // (tracking rate) that MUST be supported is driveSidereal! // - this.trackingRates = new[] { DriveRates.driveSidereal, DriveRates.driveLunar }; + _trackingRates = new[] { DriveRates.driveSidereal, DriveRates.driveLunar }; // TODO Initialize this array with any additional tracking rates that your driver may provide } #region ITrackingRates Members - public int Count - { - get { return this.trackingRates.Length; } - } + public int Count => _trackingRates.Length; public IEnumerator GetEnumerator() { - pos.Value = -1; + _pos.Value = -1; return this as IEnumerator; } @@ -198,10 +185,7 @@ namespace ASCOM.Meade.net // TODO Add any required object cleanup here } - public DriveRates this[int index] - { - get { return this.trackingRates[index - 1]; } // 1-based - } + public DriveRates this[int index] => _trackingRates[index - 1]; #endregion @@ -211,22 +195,22 @@ namespace ASCOM.Meade.net { get { - lock (lockObj) + lock (LockObj) { - if (pos.Value < 0 || pos.Value >= trackingRates.Length) + if (_pos.Value < 0 || _pos.Value >= _trackingRates.Length) { throw new System.InvalidOperationException(); } - return trackingRates[pos.Value]; + return _trackingRates[_pos.Value]; } } } public bool MoveNext() { - lock (lockObj) + lock (LockObj) { - if (++pos.Value >= trackingRates.Length) + if (++_pos.Value >= _trackingRates.Length) { return false; } @@ -236,7 +220,7 @@ namespace ASCOM.Meade.net public void Reset() { - pos.Value = -1; + _pos.Value = -1; } #endregion } diff --git a/Meade.net.Telescope/Telescope.cs b/Meade.net.Telescope/Telescope.cs index bc7af47..0ce3b53 100644 --- a/Meade.net.Telescope/Telescope.cs +++ b/Meade.net.Telescope/Telescope.cs @@ -1,45 +1,16 @@ -//tabs=4 -// -------------------------------------------------------------------------------- -// TODO fill in this information for your driver, then remove this line! -// -// ASCOM Telescope driver for Meade.net -// -// 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.Collections.Generic; -using System.Diagnostics; -using System.Text; 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 System.Globalization; using System.Reflection; +using ASCOM.Meade.net.AstroMaths; +using ASCOM.Meade.net.Wrapper; +using ASCOM.Utilities.Interfaces; namespace ASCOM.Meade.net { @@ -68,42 +39,35 @@ namespace ASCOM.Meade.net /// The DeviceID is used by ASCOM applications to load the driver at runtime. /// //internal static string driverID = "ASCOM.Meade.net.Telescope"; - internal static string driverID = Marshal.GenerateProgIdForType(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string DriverId = Marshal.GenerateProgIdForType(MethodBase.GetCurrentMethod().DeclaringType); // 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 Generic"; + private static readonly string DriverDescription = "Meade Generic"; - 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 the connected state - /// - private bool _connectedState; + private static string _comPort; // Variables to hold the currrent device configuration /// /// Private variable to hold an ASCOM Utilities object /// - private Util utilities; + private readonly IUtil _utilities; + private readonly IUtilExtra _utilitiesExtra; /// /// Private variable to hold an ASCOM AstroUtilities object to provide the Range method /// - private AstroUtils astroUtilities; + private readonly IAstroUtils _astroUtilities; - private readonly AstroMaths _astroMaths; + private readonly IAstroMaths _astroMaths; /// /// Variable to hold the trace logger object (creates a diagnostic log file with information that you specify) /// - internal static TraceLogger tl; + private TraceLogger _tl; + + private readonly ISharedResourcesWrapper _sharedResourcesWrapper; /// /// Initializes a new instance of the class. @@ -111,19 +75,39 @@ namespace ASCOM.Meade.net /// public Telescope() { - tl = new TraceLogger("", "Meade.net.Telescope"); + //todo move this out to IOC + var util = new Util(); //Initialise util object + _utilities = util; + _utilitiesExtra = util; //Initialise util object + _astroUtilities = new AstroUtils(); // Initialise astro utilities object + _sharedResourcesWrapper = new SharedResourcesWrapper(); + _astroMaths = new AstroMaths.AstroMaths(); + + Initialise(); + } + + public Telescope( IUtil util, IUtilExtra utilExtra, IAstroUtils astroUtilities, ISharedResourcesWrapper sharedResourcesWrapper, IAstroMaths astroMaths) + { + _utilities = util; //Initialise util object + _utilitiesExtra = utilExtra; //Initialise util object + _astroUtilities = astroUtilities; // Initialise astro utilities object + _sharedResourcesWrapper = sharedResourcesWrapper; + _astroMaths = astroMaths; + + Initialise(); + } + + private void Initialise() + { + //todo move the TraceLogger out to a factory class. + _tl = new TraceLogger("", "Meade.net.Telescope"); + LogMessage("Telescope", "Starting initialisation"); + ReadProfile(); // Read device configuration from the ASCOM Profile store - tl.LogMessage("Telescope", "Starting initialisation"); + IsConnected = false; // Initialise connected to false - _connectedState = false; // Initialise connected to false - utilities = new Util(); //Initialise util object - astroUtilities = new AstroUtils(); // Initialise astro utilities object - - //TODO: Implement your additional construction here - _astroMaths = new AstroMaths(); - - tl.LogMessage("Telescope", "Completed initialisation"); + LogMessage("Telescope", "Completed initialisation"); } @@ -141,10 +125,10 @@ namespace ASCOM.Meade.net /// public void SetupDialog() { - tl.LogMessage("SetupDialog", "Opening setup dialog"); - SharedResources.SetupDialog(); + LogMessage("SetupDialog", "Opening setup dialog"); + _sharedResourcesWrapper.SetupDialog(); ReadProfile(); - tl.LogMessage("SetupDialog", "complete"); + LogMessage("SetupDialog", "complete"); //// consider only showing the setup dialog if not connected //// or call a different dialog if connected //if (IsConnected) @@ -164,7 +148,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("SupportedActions Get", "Returning empty arraylist"); + LogMessage("SupportedActions Get", "Returning empty arraylist"); var supportedActions = new ArrayList(); supportedActions.Add("handbox"); return supportedActions; @@ -173,6 +157,8 @@ namespace ASCOM.Meade.net public string Action(string actionName, string actionParameters) { + CheckConnected("Action"); + switch (actionName.ToLower()) { case "handbox": @@ -180,77 +166,77 @@ namespace ASCOM.Meade.net { //Read the screen case "readdisplay": - var output = SharedResources.SendString(":ED#"); + var output = _sharedResourcesWrapper.SendString(":ED#"); return output; //top row of buttons case "enter": - SharedResources.SendBlind(":EK13#"); + _sharedResourcesWrapper.SendBlind(":EK13#"); break; case "mode": - SharedResources.SendBlind(":EK9#"); + _sharedResourcesWrapper.SendBlind(":EK9#"); break; - case "longMode": - SharedResources.SendBlind(":EK11#"); + case "longmode": + _sharedResourcesWrapper.SendBlind(":EK11#"); break; case "goto": - SharedResources.SendBlind(":EK24#"); + _sharedResourcesWrapper.SendBlind(":EK24#"); break; case "0": //light and 0 - SharedResources.SendBlind(":EK48#"); + _sharedResourcesWrapper.SendBlind(":EK48#"); break; case "1": - SharedResources.SendBlind(":EK49#"); + _sharedResourcesWrapper.SendBlind(":EK49#"); break; case "2": - SharedResources.SendBlind(":EK50#"); + _sharedResourcesWrapper.SendBlind(":EK50#"); break; case "3": - SharedResources.SendBlind(":EK51#"); + _sharedResourcesWrapper.SendBlind(":EK51#"); break; case "4": - SharedResources.SendBlind(":EK52#"); + _sharedResourcesWrapper.SendBlind(":EK52#"); break; case "5": - SharedResources.SendBlind(":EK53#"); + _sharedResourcesWrapper.SendBlind(":EK53#"); break; case "6": - SharedResources.SendBlind(":EK54#"); + _sharedResourcesWrapper.SendBlind(":EK54#"); break; case "7": - SharedResources.SendBlind(":EK55#"); + _sharedResourcesWrapper.SendBlind(":EK55#"); break; case "8": - SharedResources.SendBlind(":EK56#"); + _sharedResourcesWrapper.SendBlind(":EK56#"); break; case "9": - SharedResources.SendBlind(":EK57#"); + _sharedResourcesWrapper.SendBlind(":EK57#"); break; case "up": - SharedResources.SendBlind(":EK94#"); + _sharedResourcesWrapper.SendBlind(":EK94#"); break; case "down": - SharedResources.SendBlind(":EK118#"); + _sharedResourcesWrapper.SendBlind(":EK118#"); break; case "back": - SharedResources.SendBlind(":EK87#"); + _sharedResourcesWrapper.SendBlind(":EK87#"); break; case "forward": - SharedResources.SendBlind(":EK69#"); + _sharedResourcesWrapper.SendBlind(":EK69#"); break; case "?": - SharedResources.SendBlind(":EK63#"); + _sharedResourcesWrapper.SendBlind(":EK63#"); break; default: LogMessage("", "Action {0}, parameters {1} not implemented", actionName, actionParameters); - throw new ASCOM.ActionNotImplementedException($"Action {actionName}({actionParameters}) is not implemented by this driver"); + throw new ActionNotImplementedException($"{actionName}({actionParameters})"); } break; default: LogMessage("", "Action {0}, parameters {1} not implemented", actionName, actionParameters); - throw new ASCOM.ActionNotImplementedException($"Action {actionName} is not implemented by this driver"); + throw new ActionNotImplementedException($"{actionName}"); } return string.Empty; @@ -261,7 +247,7 @@ namespace ASCOM.Meade.net CheckConnected("CommandBlind"); // Call CommandString and return as soon as it finishes //this.CommandString(command, raw); - SharedResources.SendBlind(command); + _sharedResourcesWrapper.SendBlind(command); // or //throw new ASCOM.MethodNotImplementedException("CommandBlind"); // DO NOT have both these sections! One or the other @@ -273,7 +259,7 @@ namespace ASCOM.Meade.net //string ret = CommandString(command, raw); // TODO decode the return string and return true or false // or - throw new ASCOM.MethodNotImplementedException("CommandBool"); + throw new MethodNotImplementedException("CommandBool"); // DO NOT have both these sections! One or the other } @@ -283,20 +269,19 @@ namespace ASCOM.Meade.net // 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 - return SharedResources.SendString(command); + return _sharedResourcesWrapper.SendString(command); //throw new ASCOM.MethodNotImplementedException("CommandString"); } public void Dispose() { + if (Connected) + Connected = false; + // Clean up the tracelogger and util objects - tl.Enabled = false; - tl.Dispose(); - tl = null; - utilities.Dispose(); - utilities = null; - astroUtilities.Dispose(); - astroUtilities = null; + _tl.Enabled = false; + _tl.Dispose(); + _tl = null; } public bool Connected @@ -308,54 +293,54 @@ namespace ASCOM.Meade.net } set { - tl.LogMessage("Connected", "Set {0}", value); + LogMessage("Connected", "Set {0}", value); if (value == IsConnected) return; if (value) { - LogMessage("Connected Set", "Connecting to port {0}", comPort); + LogMessage("Connected Set", "Connecting to port {0}", _comPort); try { - SharedResources.Connect("Serial"); + _sharedResourcesWrapper.Connect("Serial"); try { - LogMessage("Connected Set", $"Commented to port {comPort}. Product: {SharedResources.ProductName} Version:{SharedResources.FirmwareVersion}"); + LogMessage("Connected Set", $"Connected to port {_comPort}. Product: {_sharedResourcesWrapper.ProductName} Version:{_sharedResourcesWrapper.FirmwareVersion}"); - - SelectSite(1); SetLongFormat(true); - - _userNewerPulseGuiding = IsNewPulseGuidingSupported(); + _targetDeclination = InvalidParameter; + _targetRightAscension = InvalidParameter; + _tracking = true; - _connectedState = true; + LogMessage("Connected Set", $"New Pulse Guiding Supported: {_userNewerPulseGuiding}"); + IsConnected = true; } catch (Exception) { - SharedResources.Disconnect("Serial"); + _sharedResourcesWrapper.Disconnect("Serial"); throw; } } catch (Exception ex) { - LogMessage("Connected Set", "Error connecting to port {0} - {1}", comPort, ex.Message); + LogMessage("Connected Set", "Error connecting to port {0} - {1}", _comPort, ex.Message); } } else { - LogMessage("Connected Set", "Disconnecting from port {0}", comPort); - SharedResources.Disconnect("Serial"); - _connectedState = false; + LogMessage("Connected Set", "Disconnecting from port {0}", _comPort); + _sharedResourcesWrapper.Disconnect("Serial"); + IsConnected = false; } } } - private bool IsNewPulseGuidingSupported() + public bool IsNewPulseGuidingSupported() { - if (SharedResources.ProductName == SharedResources.AUTOSTAR497) + if (_sharedResourcesWrapper.ProductName == _sharedResourcesWrapper.Autostar497) { - return FirmwareIsGreaterThan(SharedResources.AUTOSTAR497_31EE); + return FirmwareIsGreaterThan(_sharedResourcesWrapper.Autostar49731Ee); } return false; @@ -363,26 +348,26 @@ namespace ASCOM.Meade.net private bool FirmwareIsGreaterThan(string minVersion) { - var currentVersion = SharedResources.FirmwareVersion; - var comparison = currentVersion.CompareTo(minVersion); + var currentVersion = _sharedResourcesWrapper.FirmwareVersion; + var comparison = String.Compare(currentVersion, minVersion, StringComparison.Ordinal); return (comparison >= 0); } - private void SetLongFormat(bool setLongFormat) + public void SetLongFormat(bool setLongFormat) { - SharedResources.Lock(() => + _sharedResourcesWrapper.Lock(() => { - var result = SharedResources.SendString(":GZ#"); + var result = _sharedResourcesWrapper.SendString(":GZ#"); //:GZ# Get telescope azimuth - //Returns: DDD*MM#T or DDD*MM’SS# + //Returns: DDD*MM# or DDD*MM’SS# //The current telescope Azimuth depending on the selected precision. bool isLongFormat = result.Length > 6; if (isLongFormat != setLongFormat) { - utilities.WaitForMilliseconds(500); - SharedResources.SendBlind(":U#"); + _utilities.WaitForMilliseconds(500); + _sharedResourcesWrapper.SendBlind(":U#"); //:U# Toggle between low/hi precision positions //Low - RA displays and messages HH:MM.T sDD*MM //High - Dec / Az / El displays and messages HH:MM: SS sDD*MM:SS @@ -391,9 +376,15 @@ namespace ASCOM.Meade.net }); } - private void SelectSite(int site) + //todo hook this up to a custom action + public void SelectSite(int site) { - SharedResources.SendBlind($":W{site}#"); + if (site < 1) + throw new ArgumentOutOfRangeException("site",site,"Site cannot be lower than 1"); + else if (site > 4) + throw new ArgumentOutOfRangeException("site", site, "Site cannot be higher than 4"); + + _sharedResourcesWrapper.SendBlind($":W{site}#"); //:W# //Set current site to, an ASCII digit in the range 1..4 //Returns: Nothing @@ -404,8 +395,8 @@ namespace ASCOM.Meade.net // TODO customise this device description get { - tl.LogMessage("Description Get", driverDescription); - return driverDescription; + LogMessage("Description Get", DriverDescription); + return DriverDescription; } } @@ -413,11 +404,9 @@ namespace ASCOM.Meade.net { get { - Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; // TODO customise this driver description - string driverInfo = "Meade Generic .net driver. Version: " + String.Format(CultureInfo.InvariantCulture, "{0}.{1}", version.Major, - version.Minor); - tl.LogMessage("DriverInfo Get", driverInfo); + string driverInfo = $"{Description} .net driver. Version: {DriverVersion}"; + LogMessage("DriverInfo Get", driverInfo); return driverInfo; } } @@ -426,10 +415,9 @@ namespace ASCOM.Meade.net { get { - Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; - string driverVersion = - String.Format(CultureInfo.InvariantCulture, "{0}.{1}", version.Major, version.Minor); - tl.LogMessage("DriverVersion Get", driverVersion); + Version version = Assembly.GetExecutingAssembly().GetName().Version; + string driverVersion = $"{version.Major}.{version.Minor}.{version.Revision}.{version.Build}"; + LogMessage("DriverVersion Get", driverVersion); return driverVersion; } } @@ -450,17 +438,17 @@ namespace ASCOM.Meade.net { //string name = "Short driver name - please customise"; - //var telescopeProduceName = SharedResources.SendString(":GVP#"); + //var telescopeProduceName = _sharedResourcesWrapper.SendString(":GVP#"); ////:GVP# Get Telescope Product Name ////Returns: # - //var firmwareVersion = SharedResources.SendString(":GVN#"); + //var firmwareVersion = _sharedResourcesWrapper.SendString(":GVN#"); ////:GVN# Get Telescope Firmware Number ////Returns: dd.d# //string name = $"{telescopeProduceName} - {firmwareVersion}"; - string name = driverDescription; - tl.LogMessage("Name Get", name); + string name = DriverDescription; + LogMessage("Name Get", name); return name; } } @@ -473,23 +461,26 @@ namespace ASCOM.Meade.net { CheckConnected("AbortSlew"); - tl.LogMessage("AbortSlew", "Aborting slew"); - SharedResources.SendBlind(":Q#"); + LogMessage("AbortSlew", "Aborting slew"); + _sharedResourcesWrapper.SendBlind(":Q#"); //:Q# Halt all current slewing //Returns:Nothing + + _movingPrimary = false; + _movingSecondary = false; } public AlignmentModes AlignmentMode { get { - tl.LogMessage("AlignmentMode Get", "Getting alignmode"); + LogMessage("AlignmentMode Get", "Getting alignmode"); CheckConnected("AlignmentMode Get"); const char ack = (char) 6; - var alignmentString = SharedResources.SendChar(ack.ToString()); + var alignmentString = _sharedResourcesWrapper.SendChar(ack.ToString()); //ACK <0x06> Query of alignment mounting mode. //Returns: //A If scope in AltAz Mode @@ -497,14 +488,17 @@ namespace ASCOM.Meade.net //L If scope in Land Mode //P If scope in Polar Mode - //todo implement GW Command - //var alignmentString = SerialPort.CommandTerminated(":GW#", "#"); - //:GW# Get Scope Alignment Status - //Returns: # - // where: - //mount: A - AzEl mounted, P - Equatorially mounted, G - german mounted equatorial - //tracking: T - tracking, N - not tracking - //alignment: 0 - needs alignment, 1 - one star aligned, 2 - two star aligned, 3 - three star aligned. + //todo implement GW Command - Supported in Autostar 43Eg and above + //if FirmwareIsGreaterThan(_sharedResourcesWrapper.AUTOSTAR497_43EG) + //{ + //var alignmentString = SerialPort.CommandTerminated(":GW#", "#"); + //:GW# Get Scope Alignment Status + //Returns: # + // where: + //mount: A - AzEl mounted, P - Equatorially mounted, G - german mounted equatorial + //tracking: T - tracking, N - not tracking + //alignment: 0 - needs alignment, 1 - one star aligned, 2 - two star aligned, 3 - three star aligned. + //} AlignmentModes alignmentMode; switch (alignmentString) @@ -523,23 +517,29 @@ namespace ASCOM.Meade.net $"unknown alignment returned from telescope: {alignmentString}"); } - tl.LogMessage("AlignmentMode Get", $"alignmode = {alignmentMode}"); + LogMessage("AlignmentMode Get", $"alignmode = {alignmentMode}"); return alignmentMode; } set { CheckConnected("AlignmentMode Set"); - switch (value) + //todo tidy this up into a better solution that means can :GW#, :AL#, :AA#, & :AP# and checked for Autostar properly + if (!FirmwareIsGreaterThan(_sharedResourcesWrapper.Autostar49743Eg)) + throw new PropertyNotImplementedException("AlignmentMode",true ); + + //todo make this only try with Autostar 43Eg and above. + + switch (value) { case AlignmentModes.algAltAz: - SharedResources.SendBlind(":AA#"); + _sharedResourcesWrapper.SendBlind(":AA#"); //:AA# Sets telescope the AltAz alignment mode //Returns: nothing break; case AlignmentModes.algPolar: case AlignmentModes.algGermanPolar: - SharedResources.SendBlind(":AP#"); + _sharedResourcesWrapper.SendBlind(":AP#"); //:AP# Sets telescope to Polar alignment mode //Returns: nothing break; @@ -556,44 +556,44 @@ namespace ASCOM.Meade.net { get { - CheckConnected("Altitude get"); + CheckConnected("Altitude Get"); var altAz = CalcAltAzFromTelescopeEqData(); - tl.LogMessage("Altitude", $"{altAz.Altitude}"); + LogMessage("Altitude", $"{altAz.Altitude}"); return altAz.Altitude; ////todo firmware bug in 44Eg, :GA# is returning the dec, not the altitude! - //var result = SharedResources.SendString(":GA#"); + //var result = _sharedResourcesWrapper.SendString(":GA#"); ////:GA# Get Telescope Altitude ////Returns: sDD* MM# or sDD*MM’SS# ////The current scope altitude. The returned format depending on the current precision setting. //var alt = utilities.DMSToDegrees(result); - //tl.LogMessage("Altitude", $"{alt}"); + //LogMessage("Altitude", $"{alt}"); //return alt; - //tl.LogMessage("Altitude Get", "Not implemented"); + //LogMessage("Altitude Get", "Not implemented"); //throw new ASCOM.PropertyNotImplementedException("Altitude", false); } } private HorizonCoordinates CalcAltAzFromTelescopeEqData() { - var altitudeData = SharedResources.Lock(() => new AltitudeData + var altitudeData = _sharedResourcesWrapper.Lock(() => new AltitudeData { - UtcDateTime = this.UTCDate, - SiteLongitude = this.SiteLongitude, - SiteLatitude = this.SiteLatitude, - equatorialCoordinates = new EquatorialCoordinates() + UtcDateTime = UTCDate, + SiteLongitude = SiteLongitude, + SiteLatitude = SiteLatitude, + EquatorialCoordinates = new EquatorialCoordinates() { - RightAscension = this.RightAscension, - Declination = this.Declination + RightAscension = RightAscension, + Declination = Declination } }); double hourAngle = _astroMaths.RightAscensionToHourAngle(altitudeData.UtcDateTime, altitudeData.SiteLongitude, - altitudeData.equatorialCoordinates.RightAscension); - var altAz = _astroMaths.ConvertEqToHoz(hourAngle, altitudeData.SiteLatitude, altitudeData.equatorialCoordinates); + altitudeData.EquatorialCoordinates.RightAscension); + var altAz = _astroMaths.ConvertEqToHoz(hourAngle, altitudeData.SiteLatitude, altitudeData.EquatorialCoordinates); return altAz; } @@ -601,8 +601,8 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("ApertureArea Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("ApertureArea", false); + LogMessage("ApertureArea Get", "Not implemented"); + throw new PropertyNotImplementedException("ApertureArea", false); } } @@ -610,8 +610,8 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("ApertureDiameter Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("ApertureDiameter", false); + LogMessage("ApertureDiameter Get", "Not implemented"); + throw new PropertyNotImplementedException("ApertureDiameter", false); } } @@ -619,7 +619,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("AtHome", "Get - " + false.ToString()); + LogMessage("AtHome", "Get - " + false.ToString()); return false; } } @@ -630,36 +630,36 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("AtPark", "Get - " + _atPark); + LogMessage("AtPark", "Get - " + _atPark); return _atPark; } - private set { _atPark = value; } + private set => _atPark = value; } - public IAxisRates AxisRates(TelescopeAxes Axis) + public IAxisRates AxisRates(TelescopeAxes axis) { - tl.LogMessage("AxisRates", "Get - " + Axis.ToString()); - return new AxisRates(Axis); + LogMessage("AxisRates", "Get - " + axis.ToString()); + return new AxisRates(axis); } public double Azimuth { get { - CheckConnected("Azimuth get"); + CheckConnected("Azimuth Get"); - //var result = SharedResources.SendString(":GZ#"); + //var result = _sharedResourcesWrapper.SendString(":GZ#"); //:GZ# Get telescope azimuth //Returns: DDD*MM#T or DDD*MM’SS# //The current telescope Azimuth depending on the selected precision. //double az = utilities.DMSToDegrees(result); - //tl.LogMessage("Azimuth Get", $"{az}"); + //LogMessage("Azimuth Get", $"{az}"); //return az; var altAz = CalcAltAzFromTelescopeEqData(); - tl.LogMessage("Azimuth Get", $"{altAz.Azimuth}"); + LogMessage("Azimuth Get", $"{altAz.Azimuth}"); return altAz.Azimuth; } } @@ -668,20 +668,20 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanFindHome", "Get - " + false.ToString()); + LogMessage("CanFindHome", "Get - " + false.ToString()); return false; } } - public bool CanMoveAxis(TelescopeAxes Axis) + public bool CanMoveAxis(TelescopeAxes axis) { - tl.LogMessage("CanMoveAxis", "Get - " + Axis.ToString()); - switch (Axis) + 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"); + default: throw new InvalidValueException("CanMoveAxis", axis.ToString(), "0 to 2"); } } @@ -689,7 +689,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanPark", "Get - " + true.ToString()); + LogMessage("CanPark", "Get - " + true.ToString()); return true; } } @@ -698,7 +698,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanPulseGuide", "Get - " + true.ToString()); + LogMessage("CanPulseGuide", "Get - " + true.ToString()); return true; } } @@ -707,7 +707,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetDeclinationRate", "Get - " + false.ToString()); + LogMessage("CanSetDeclinationRate", "Get - " + false.ToString()); return false; } } @@ -716,7 +716,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetGuideRates", "Get - " + false.ToString()); + LogMessage("CanSetGuideRates", "Get - " + false.ToString()); return false; } } @@ -725,7 +725,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetPark", "Get - " + false.ToString()); + LogMessage("CanSetPark", "Get - " + false.ToString()); return false; } } @@ -734,7 +734,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetPierSide", "Get - " + false.ToString()); + LogMessage("CanSetPierSide", "Get - " + false.ToString()); return false; } } @@ -743,7 +743,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetRightAscensionRate", "Get - " + false.ToString()); + LogMessage("CanSetRightAscensionRate", "Get - " + false.ToString()); return false; } } @@ -752,7 +752,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetTracking", "Get - " + true.ToString()); + LogMessage("CanSetTracking", "Get - " + true.ToString()); return true; } } @@ -761,7 +761,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSlew", "Get - " + true.ToString()); + LogMessage("CanSlew", "Get - " + true.ToString()); return true; } } @@ -770,7 +770,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSlewAltAz", "Get - " + true.ToString()); + LogMessage("CanSlewAltAz", "Get - " + true.ToString()); return true; } } @@ -779,7 +779,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSlewAltAzAsync", "Get - " + true.ToString()); + LogMessage("CanSlewAltAzAsync", "Get - " + true.ToString()); return true; } } @@ -788,7 +788,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSlewAsync", "Get - " + true.ToString()); + LogMessage("CanSlewAsync", "Get - " + true.ToString()); return true; } } @@ -797,7 +797,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSync", "Get - " + true.ToString()); + LogMessage("CanSync", "Get - " + true.ToString()); return true; } } @@ -806,7 +806,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSyncAltAz", "Get - " + false.ToString()); + LogMessage("CanSyncAltAz", "Get - " + false.ToString()); return false; } } @@ -815,7 +815,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanUnpark", "Get - " + false.ToString()); + LogMessage("CanUnpark", "Get - " + false.ToString()); return false; } } @@ -826,14 +826,14 @@ namespace ASCOM.Meade.net { CheckConnected("Declination Get"); - var result = SharedResources.SendString(":GD#"); + var result = _sharedResourcesWrapper.SendString(":GD#"); //:GD# Get Telescope Declination. - //Returns: sDD* MM# or sDD*MM’SS# + //Returns: sDD*MM# or sDD*MM’SS# //Depending upon the current precision setting for the telescope. - double declination = utilities.DMSToDegrees(result); + double declination = _utilities.DMSToDegrees(result); - tl.LogMessage("Declination", "Get - " + utilities.DegreesToDMS(declination, ":", ":")); + LogMessage("Declination", "Get - " + _utilitiesExtra.DegreesToDMS(declination, ":", ":")); return declination; } } @@ -843,33 +843,33 @@ namespace ASCOM.Meade.net get { double declination = 0.0; - tl.LogMessage("DeclinationRate", "Get - " + declination.ToString()); + LogMessage("DeclinationRate", "Get - " + declination.ToString(CultureInfo.InvariantCulture)); return declination; } set { - tl.LogMessage("DeclinationRate Set", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("DeclinationRate", true); + LogMessage("DeclinationRate Set", "Not implemented"); + throw new PropertyNotImplementedException("DeclinationRate", true); } } public PierSide DestinationSideOfPier(double rightAscension, double declination) { - tl.LogMessage("DestinationSideOfPier Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("DestinationSideOfPier", false); + LogMessage("DestinationSideOfPier Get", "Not implemented"); + throw new MethodNotImplementedException("DestinationSideOfPier"); } public bool DoesRefraction { get { - tl.LogMessage("DoesRefraction Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("DoesRefraction", false); + LogMessage("DoesRefraction Get", "Not implemented"); + throw new PropertyNotImplementedException("DoesRefraction", false); } set { - tl.LogMessage("DoesRefraction Set", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("DoesRefraction", true); + LogMessage("DoesRefraction Set", "Not implemented"); + throw new PropertyNotImplementedException("DoesRefraction", true); } } @@ -878,23 +878,23 @@ namespace ASCOM.Meade.net get { EquatorialCoordinateType equatorialSystem = EquatorialCoordinateType.equTopocentric; - tl.LogMessage("DeclinationRate", "Get - " + equatorialSystem.ToString()); + LogMessage("DeclinationRate", "Get - " + equatorialSystem.ToString()); return equatorialSystem; } } public void FindHome() { - tl.LogMessage("FindHome", "Not implemented"); - throw new ASCOM.MethodNotImplementedException("FindHome"); + LogMessage("FindHome", "Not implemented"); + throw new MethodNotImplementedException("FindHome"); } public double FocalLength { get { - tl.LogMessage("FocalLength Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("FocalLength", false); + LogMessage("FocalLength Get", "Not implemented"); + throw new PropertyNotImplementedException("FocalLength", false); } } @@ -902,13 +902,13 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("GuideRateDeclination Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("GuideRateDeclination", false); + LogMessage("GuideRateDeclination Get", "Not implemented"); + throw new PropertyNotImplementedException("GuideRateDeclination", false); } set { - tl.LogMessage("GuideRateDeclination Set", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("GuideRateDeclination", true); + LogMessage("GuideRateDeclination Set", "Not implemented"); + throw new PropertyNotImplementedException("GuideRateDeclination", true); } } @@ -916,13 +916,13 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("GuideRateRightAscension Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("GuideRateRightAscension", false); + LogMessage("GuideRateRightAscension Get", "Not implemented"); + throw new PropertyNotImplementedException("GuideRateRightAscension", false); } set { - tl.LogMessage("GuideRateRightAscension Set", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("GuideRateRightAscension", true); + LogMessage("GuideRateRightAscension Set", "Not implemented"); + throw new PropertyNotImplementedException("GuideRateRightAscension", true); } } @@ -930,7 +930,8 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("IsPulseGuiding Get", "pulse guiding is synchronous for this driver"); + //Todo implement this if I can make the new pulse guiding async + LogMessage("IsPulseGuiding Get", "pulse guiding is synchronous for this driver"); //throw new ASCOM.PropertyNotImplementedException("IsPulseGuiding", false); return false; } @@ -941,7 +942,7 @@ namespace ASCOM.Meade.net public void MoveAxis(TelescopeAxes axis, double rate) { - tl.LogMessage("MoveAxis", $"Axis={axis} rate={rate}"); + LogMessage("MoveAxis", $"Axis={axis} rate={rate}"); CheckConnected("MoveAxis"); var absRate = Math.Abs(rate); @@ -952,27 +953,27 @@ namespace ASCOM.Meade.net //do nothing, it's ok this time as we're halting the slew. break; case 1: - SharedResources.SendBlind(":RG#"); + _sharedResourcesWrapper.SendBlind(":RG#"); //:RG# Set Slew rate to Guiding Rate (slowest) //Returns: Nothing break; case 2: - SharedResources.SendBlind(":RC#"); + _sharedResourcesWrapper.SendBlind(":RC#"); //:RC# Set Slew rate to Centering rate (2nd slowest) //Returns: Nothing break; case 3: - SharedResources.SendBlind(":RM#"); + _sharedResourcesWrapper.SendBlind(":RM#"); //:RM# Set Slew rate to Find Rate (2nd Fastest) //Returns: Nothing break; case 4: - SharedResources.SendBlind(":RS#"); + _sharedResourcesWrapper.SendBlind(":RS#"); //:RS# Set Slew rate to max (fastest) //Returns: Nothing break; default: - throw new ASCOM.InvalidValueException($"Rate {rate} not supported"); + throw new InvalidValueException($"Rate {rate} not supported"); } switch (axis) @@ -981,23 +982,23 @@ namespace ASCOM.Meade.net if (rate == 0) { _movingPrimary = false; - SharedResources.SendBlind(":Qe#"); + _sharedResourcesWrapper.SendBlind(":Qe#"); //:Qe# Halt eastward Slews //Returns: Nothing - SharedResources.SendBlind(":Qw#"); + _sharedResourcesWrapper.SendBlind(":Qw#"); //:Qw# Halt westward Slews //Returns: Nothing } else if (rate > 0) { - SharedResources.SendBlind(":Me#"); + _sharedResourcesWrapper.SendBlind(":Me#"); //:Me# Move Telescope East at current slew rate //Returns: Nothing _movingPrimary = true; } else { - SharedResources.SendBlind(":Mw#"); + _sharedResourcesWrapper.SendBlind(":Mw#"); //:Mw# Move Telescope West at current slew rate //Returns: Nothing _movingPrimary = true; @@ -1008,23 +1009,23 @@ namespace ASCOM.Meade.net if (rate == 0) { _movingSecondary = false; - SharedResources.SendBlind(":Qn#"); + _sharedResourcesWrapper.SendBlind(":Qn#"); //:Qn# Halt northward Slews //Returns: Nothing - SharedResources.SendBlind(":Qs#"); + _sharedResourcesWrapper.SendBlind(":Qs#"); //:Qs# Halt southward Slews //Returns: Nothing } else if (rate > 0) { - SharedResources.SendBlind(":Mn#"); + _sharedResourcesWrapper.SendBlind(":Mn#"); //:Mn# Move Telescope North at current slew rate //Returns: Nothing _movingSecondary = true; } else { - SharedResources.SendBlind(":Ms#"); + _sharedResourcesWrapper.SendBlind(":Ms#"); //:Ms# Move Telescope South at current slew rate //Returns: Nothing _movingSecondary = true; @@ -1032,19 +1033,19 @@ namespace ASCOM.Meade.net break; default: - throw new ASCOM.MethodNotImplementedException("Can not move this axis."); + throw new InvalidValueException("Can not move this axis."); } } public void Park() { - tl.LogMessage("Park", "Parking telescope"); + LogMessage("Park", "Parking telescope"); CheckConnected("Park"); if (AtPark) return; - SharedResources.SendBlind(":hP#"); + _sharedResourcesWrapper.SendBlind(":hP#"); //:hP# Autostar, Autostar II and LX 16”Slew to Park Position //Returns: Nothing AtPark = true; @@ -1054,7 +1055,7 @@ namespace ASCOM.Meade.net public void PulseGuide(GuideDirections direction, int duration) { - tl.LogMessage("PulseGuide", $"pulse guide direction {direction} duration {duration}"); + LogMessage("PulseGuide", $"pulse guide direction {direction} duration {duration}"); CheckConnected("PulseGuide"); string d = string.Empty; @@ -1076,7 +1077,7 @@ namespace ASCOM.Meade.net if (_userNewerPulseGuiding) { - SharedResources.SendBlind($":Mg{d}{duration:0000}#"); + _sharedResourcesWrapper.SendBlind($":Mg{d}{duration:0000}#"); //:MgnDDDD# //:MgsDDDD# //:MgeDDDD# @@ -1086,16 +1087,17 @@ namespace ASCOM.Meade.net //Returns – Nothing //LX200 – Not Supported - utilities.WaitForMilliseconds(duration); //todo figure out if this is really needed + //todo implement IsPulseGuiding if WaitForMilliseconds is not needed + _utilities.WaitForMilliseconds(duration); //todo figure out if this is really needed } else { - SharedResources.Lock(() => + _sharedResourcesWrapper.Lock(() => { - SharedResources.SendBlind(":RG#"); //Make sure we are at guide rate + _sharedResourcesWrapper.SendBlind(":RG#"); //Make sure we are at guide rate //:RG# Set Slew rate to Guiding Rate (slowest) //Returns: Nothing - SharedResources.SendBlind($":M{d}#"); + _sharedResourcesWrapper.SendBlind($":M{d}#"); //:Me# Move Telescope East at current slew rate //Returns: Nothing //:Mn# Move Telescope North at current slew rate @@ -1104,8 +1106,8 @@ namespace ASCOM.Meade.net //Returns: Nothing //:Mw# Move Telescope West at current slew rate //Returns: Nothing - utilities.WaitForMilliseconds(duration); - SharedResources.SendBlind($":Q{d}#"); + _utilities.WaitForMilliseconds(duration); + _sharedResourcesWrapper.SendBlind($":Q{d}#"); //:Qe# Halt eastward Slews //Returns: Nothing //:Qn# Halt northward Slews @@ -1123,14 +1125,14 @@ namespace ASCOM.Meade.net get { CheckConnected("RightAscension Get"); - var result = SharedResources.SendString(":GR#"); + var result = _sharedResourcesWrapper.SendString(":GR#"); //:GR# Get Telescope RA //Returns: HH: MM.T# or HH:MM:SS# //Depending which precision is set for the telescope - double rightAscension = utilities.HMSToHours(result); + double rightAscension = _utilities.HMSToHours(result); - tl.LogMessage("RightAscension", "Get - " + utilities.HoursToHMS(rightAscension)); + LogMessage("RightAscension", "Get - " + _utilitiesExtra.HoursToHMS(rightAscension)); return rightAscension; } } @@ -1140,33 +1142,33 @@ namespace ASCOM.Meade.net get { double rightAscensionRate = 0.0; - tl.LogMessage("RightAscensionRate", "Get - " + rightAscensionRate.ToString()); + LogMessage("RightAscensionRate", "Get - " + rightAscensionRate.ToString(CultureInfo.InvariantCulture)); return rightAscensionRate; } set { - tl.LogMessage("RightAscensionRate Set", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("RightAscensionRate", true); + LogMessage("RightAscensionRate Set", "Not implemented"); + throw new PropertyNotImplementedException("RightAscensionRate", true); } } public void SetPark() { - tl.LogMessage("SetPark", "Not implemented"); - throw new ASCOM.MethodNotImplementedException("SetPark"); + LogMessage("SetPark", "Not implemented"); + throw new MethodNotImplementedException("SetPark"); } public PierSide SideOfPier { get { - tl.LogMessage("SideOfPier Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("SideOfPier", false); + LogMessage("SideOfPier Get", "Not implemented"); + throw new PropertyNotImplementedException("SideOfPier", false); } set { - tl.LogMessage("SideOfPier Set", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("SideOfPier", true); + LogMessage("SideOfPier Set", "Not implemented"); + throw new PropertyNotImplementedException("SideOfPier", true); } } @@ -1176,22 +1178,22 @@ namespace ASCOM.Meade.net { // Now using NOVAS 3.1 double siderealTime = 0.0; - using (var novas = new ASCOM.Astrometry.NOVAS.NOVAS31()) + using (var novas = new Astrometry.NOVAS.NOVAS31()) { - var jd = utilities.DateUTCToJulian(DateTime.UtcNow); + 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); + Astrometry.GstType.GreenwichApparentSiderealTime, + Astrometry.Method.EquinoxBased, + 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); + siderealTime = _astroUtilities.ConditionRA(siderealTime); - tl.LogMessage("SiderealTime", "Get - " + siderealTime.ToString()); + LogMessage("SiderealTime", "Get - " + siderealTime.ToString(CultureInfo.InvariantCulture)); return siderealTime; } } @@ -1200,13 +1202,13 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("SiteElevation Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("SiteElevation", false); + LogMessage("SiteElevation Get", "Not implemented"); + throw new PropertyNotImplementedException("SiteElevation", false); } set { - tl.LogMessage("SiteElevation Set", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("SiteElevation", true); + LogMessage("SiteElevation Set", "Not implemented"); + throw new PropertyNotImplementedException("SiteElevation", true); } } @@ -1216,18 +1218,18 @@ namespace ASCOM.Meade.net { CheckConnected("SiteLatitude Get"); - var latitude = SharedResources.SendString(":Gt#"); + var latitude = _sharedResourcesWrapper.SendString(":Gt#"); //:Gt# Get Current Site Latitude //Returns: sDD* MM# //The latitude of the current site. Positive inplies North latitude. - var siteLatitude = utilities.DMSToDegrees(latitude); - tl.LogMessage("SiteLatitude Get", $"{utilities.DegreesToDMS(siteLatitude)}"); + var siteLatitude = _utilities.DMSToDegrees(latitude); + LogMessage("SiteLatitude Get", $"{_utilitiesExtra.DegreesToDMS(siteLatitude)}"); return siteLatitude; } set { - tl.LogMessage("SiteLatitude Set", $"{utilities.DegreesToDMS(value)}"); + LogMessage("SiteLatitude Set", $"{_utilitiesExtra.DegreesToDMS(value)}"); CheckConnected("SiteLatitude Set"); @@ -1238,10 +1240,13 @@ namespace ASCOM.Meade.net throw new InvalidValueException("Latitude cannot be less than -90 degrees."); string sign = value > 0 ? "+" : "-"; - int d = Convert.ToInt32(Math.Floor(value)); - int m = Convert.ToInt32(60 * (value - d)); - var result = SharedResources.SendChar($":St{sign}{d:00}*{m:00}#"); + var absValue = Math.Abs(value); + int d = Convert.ToInt32(Math.Floor(absValue)); + int m = Convert.ToInt32(60 * (absValue - d)); + var commandString = $":St{sign}{d:00}*{m:00}#"; + + var result = _sharedResourcesWrapper.SendChar(commandString); //:StsDD*MM# //Sets the current site latitude to sDD* MM# //Returns: @@ -1258,25 +1263,25 @@ namespace ASCOM.Meade.net { CheckConnected("SiteLongitude Get"); - var longitude = SharedResources.SendString(":Gg#"); + var longitude = _sharedResourcesWrapper.SendString(":Gg#"); //:Gg# Get Current Site Longitude - //Returns: sDDD* MM# + //Returns: sDDD*MM# //The current site Longitude. East Longitudes are expressed as negative - double siteLongitude = utilities.DMSToDegrees(longitude); + double siteLongitude = _utilities.DMSToDegrees(longitude); if (siteLongitude > 180) siteLongitude = siteLongitude - 360; siteLongitude = -siteLongitude; - tl.LogMessage("SiteLongitude Get", $"{utilities.DegreesToDMS(siteLongitude)}"); + LogMessage("SiteLongitude Get", $"{_utilitiesExtra.DegreesToDMS(siteLongitude)}"); return siteLongitude; } set { var newLongitude = value; - tl.LogMessage("SiteLongitude Set", $"{utilities.DegreesToDMS(newLongitude)}"); + LogMessage("SiteLongitude Set", $"{_utilitiesExtra.DegreesToDMS(newLongitude)}"); CheckConnected("SiteLongitude Set"); @@ -1294,7 +1299,9 @@ namespace ASCOM.Meade.net int d = Convert.ToInt32(Math.Floor(newLongitude)); int m = Convert.ToInt32(60 * (newLongitude - d)); - var result = SharedResources.SendChar($":Sg{d:000}*{m:00}#"); + var commandstring = $":Sg{d:000}*{m:00}#"; + + var result = _sharedResourcesWrapper.SendChar(commandstring); //:SgDDD*MM# //Set current site’s longitude to DDD*MM an ASCII position string //Returns: @@ -1309,26 +1316,26 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("SlewSettleTime Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("SlewSettleTime", false); + LogMessage("SlewSettleTime Get", "Not implemented"); + throw new PropertyNotImplementedException("SlewSettleTime", false); } set { - tl.LogMessage("SlewSettleTime Set", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("SlewSettleTime", true); + LogMessage("SlewSettleTime Set", "Not implemented"); + throw new PropertyNotImplementedException("SlewSettleTime", true); } } public void SlewToAltAz(double azimuth, double altitude) { - tl.LogMessage("SlewToAltAz", $"Az=~{azimuth} Alt={altitude}"); + LogMessage("SlewToAltAz", $"Az=~{azimuth} Alt={altitude}"); CheckConnected("SlewToAltAz"); SlewToAltAzAsync(azimuth, altitude); while (Slewing) //wait for slew to complete { - utilities.WaitForMilliseconds(200); //be responsive to AbortSlew(); + _utilities.WaitForMilliseconds(200); //be responsive to AbortSlew(); } } @@ -1337,19 +1344,19 @@ namespace ASCOM.Meade.net set { if (value > 90) - throw new ASCOM.InvalidValueException("Altitude cannot be greater than 90."); + throw new InvalidValueException("Altitude cannot be greater than 90."); if (value < 0) - throw new ASCOM.InvalidValueException("Altitide cannot be less than 0."); + throw new InvalidValueException("Altitide cannot be less than 0."); CheckConnected("TargetAltitude Set"); //todo this serial string does not work. Calculate the EQ version instead. - var dms = utilities.DegreesToDMS(value, "*", "'", "",0); - var s = value < 0 ? "-" : "+"; + var dms = _utilities.DegreesToDMS(value, "*", "'", "",0); + var s = value < 0 ? string.Empty : "+"; - var result = SharedResources.SendChar($":Sa{s}{dms}#"); + var result = _sharedResourcesWrapper.SendChar($":Sa{s}{dms}#"); //:SasDD*MM# //Set target object altitude to sDD*MM# or sDD*MM’SS# [LX 16”, Autostar, Autostar II] //Returns: @@ -1357,7 +1364,7 @@ namespace ASCOM.Meade.net //0 Object out of slew range if (result == "0") - throw new ASCOM.InvalidOperationException("Target altitude out of slew range"); + throw new InvalidOperationException("Target altitude out of slew range"); } } @@ -1366,18 +1373,18 @@ namespace ASCOM.Meade.net set { if (value >= 360) - throw new ASCOM.InvalidValueException("Azimuth cannot be 360 or higher."); + throw new InvalidValueException("Azimuth cannot be 360 or higher."); if (value < 0) - throw new ASCOM.InvalidValueException("Azimuth cannot be less than 0."); + throw new InvalidValueException("Azimuth cannot be less than 0."); CheckConnected("TargetAzimuth Set"); //todo this serial string does not work. Calculate the EQ version instead. - var dms = utilities.DegreesToDM(value, "*" ); + var dms = _utilitiesExtra.DegreesToDM(value, "*" ); - var result = SharedResources.SendChar($":Sz{dms}#"); + var result = _sharedResourcesWrapper.SendChar($":Sz{dms}#"); //:SzDDD*MM# //Sets the target Object Azimuth[LX 16” and Autostar II only] //Returns: @@ -1385,28 +1392,29 @@ namespace ASCOM.Meade.net //1 - Valid if (result == "0") - throw new ASCOM.InvalidOperationException("Target Azimuth out of slew range"); + throw new InvalidOperationException("Target Azimuth out of slew range"); } } public void SlewToAltAzAsync(double azimuth, double altitude) { - if (altitude > 90) - throw new ASCOM.InvalidValueException("Altitude cannot be greater than 90."); - - if (altitude < 0) - throw new ASCOM.InvalidValueException("Altitide cannot be less than 0."); - - if (azimuth >= 360) - throw new ASCOM.InvalidValueException("Azimuth cannot be 360 or higher."); - - if (azimuth < 0) - throw new ASCOM.InvalidValueException("Azimuth cannot be less than 0."); - - tl.LogMessage("SlewToAltAzAsync", $"Az={azimuth} Alt={altitude}"); CheckConnected("SlewToAltAzAsync"); + if (altitude > 90) + throw new InvalidValueException("Altitude cannot be greater than 90."); + + if (altitude < 0) + throw new InvalidValueException("Altitide cannot be less than 0."); + + if (azimuth >= 360) + throw new InvalidValueException("Azimuth cannot be 360 or higher."); + + if (azimuth < 0) + throw new InvalidValueException("Azimuth cannot be less than 0."); + + LogMessage("SlewToAltAzAsync", $"Az={azimuth} Alt={altitude}"); + HorizonCoordinates altAz = new HorizonCoordinates(); altAz.Azimuth = azimuth; altAz.Altitude = altitude; @@ -1415,7 +1423,7 @@ namespace ASCOM.Meade.net var latitude = SiteLatitude; var longitude = SiteLongitude; - SharedResources.Lock(() => + _sharedResourcesWrapper.Lock(() => { var raDec = _astroMaths.ConvertHozToEq(utcDateTime, latitude, longitude, altAz); @@ -1435,12 +1443,12 @@ namespace ASCOM.Meade.net { CheckConnected("DoSlewAsync"); - SharedResources.Lock(() => + _sharedResourcesWrapper.Lock(() => { switch (polar) { case true: - var response = SharedResources.SendChar(":MS#"); + var response = _sharedResourcesWrapper.SendChar(":MS#"); //:MS# Slew to Target Object //Returns: //0 Slew is Possible @@ -1451,27 +1459,27 @@ namespace ASCOM.Meade.net { case "0": //We're slewing everything should be working just fine. - tl.LogMessage("DoSlewAsync", "Slewing to target"); + LogMessage("DoSlewAsync", "Slewing to target"); break; case "1": //Below Horizon - string belowHorizonMessage = SharedResources.ReadTerminated(); - tl.LogMessage("DoSlewAsync", $"Slew failed \"{belowHorizonMessage}\""); - throw new ASCOM.InvalidOperationException(belowHorizonMessage); + string belowHorizonMessage = _sharedResourcesWrapper.ReadTerminated(); + LogMessage("DoSlewAsync", $"Slew failed \"{belowHorizonMessage}\""); + throw new InvalidOperationException(belowHorizonMessage); case "2": //Below Horizon - string belowMinimumElevationMessage = SharedResources.ReadTerminated(); - tl.LogMessage("DoSlewAsync", $"Slew failed \"{belowMinimumElevationMessage}\""); - throw new ASCOM.InvalidOperationException(belowMinimumElevationMessage); + string belowMinimumElevationMessage = _sharedResourcesWrapper.ReadTerminated(); + LogMessage("DoSlewAsync", $"Slew failed \"{belowMinimumElevationMessage}\""); + throw new InvalidOperationException(belowMinimumElevationMessage); default: - tl.LogMessage("DoSlewAsync", $"Slew failed - unknown response \"{response}\""); - throw new ASCOM.DriverException("This error should not happen"); + LogMessage("DoSlewAsync", $"Slew failed - unknown response \"{response}\""); + throw new DriverException("This error should not happen"); } break; case false: - var maResponse = SharedResources.SendChar(":MA#"); + var maResponse = _sharedResourcesWrapper.SendChar(":MA#"); //:MA# Autostar, LX 16”, Autostar II – Slew to target Alt and Az //Returns: //0 - No fault @@ -1480,7 +1488,7 @@ namespace ASCOM.Meade.net if (maResponse == "1") { - throw new ASCOM.InvalidOperationException("fault"); + throw new InvalidOperationException("fault"); } break; @@ -1490,25 +1498,25 @@ namespace ASCOM.Meade.net public void SlewToCoordinates(double rightAscension, double declination) { - tl.LogMessage("SlewToCoordinates", $"Ra={rightAscension}, Dec={declination}"); + LogMessage("SlewToCoordinates", $"Ra={rightAscension}, Dec={declination}"); CheckConnected("SlewToCoordinates"); SlewToCoordinatesAsync(rightAscension, declination); while (Slewing) //wait for slew to complete { - utilities.WaitForMilliseconds(200); //be responsive to AbortSlew(); + _utilities.WaitForMilliseconds(200); //be responsive to AbortSlew(); } - tl.LogMessage("SlewToCoordinates", $"Slewing completed new coordinates Ra={RightAscension}, Dec={Declination}"); + LogMessage("SlewToCoordinates", $"Slewing completed new coordinates Ra={RightAscension}, Dec={Declination}"); } public void SlewToCoordinatesAsync(double rightAscension, double declination) { - tl.LogMessage("SlewToCoordinatesAsync", $"Ra={rightAscension}, Dec={declination}"); + LogMessage("SlewToCoordinatesAsync", $"Ra={rightAscension}, Dec={declination}"); CheckConnected("SlewToCoordinatesAsync"); - SharedResources.Lock(() => + _sharedResourcesWrapper.Lock(() => { TargetRightAscension = rightAscension; TargetDeclination = declination; @@ -1520,29 +1528,29 @@ namespace ASCOM.Meade.net public void SlewToTarget() { - tl.LogMessage("SlewToTarget", "Executing"); + LogMessage("SlewToTarget", "Executing"); CheckConnected("SlewToTarget"); SlewToTargetAsync(); while (Slewing) { - utilities.WaitForMilliseconds(200); + _utilities.WaitForMilliseconds(200); } } - private const double INVALID_PARAMETER = -1000; + private const double InvalidParameter = -1000; public void SlewToTargetAsync() { CheckConnected("SlewToTargetAsync"); - if (TargetDeclination == INVALID_PARAMETER || TargetRightAscension == INVALID_PARAMETER) - throw new ASCOM.InvalidOperationException("No target selected to slew to."); + if (TargetDeclination == InvalidParameter || TargetRightAscension == InvalidParameter) + throw new InvalidOperationException("No target selected to slew to."); DoSlewAsync(true); } - private bool movingAxis() + private bool MovingAxis() { return _movingPrimary || _movingSecondary; } @@ -1554,35 +1562,41 @@ namespace ASCOM.Meade.net if (!Connected) return false; - if (movingAxis()) + if (MovingAxis()) return true; CheckConnected("Slewing Get"); - var result = SharedResources.SendString(":D#"); + var result = _sharedResourcesWrapper.SendString(":D#"); //:D# Requests a string of bars indicating the distance to the current target location. //Returns: //LX200's – a string of bar characters indicating the distance. //Autostars and Autostar II – a string containing one bar until a slew is complete, then a null string is returned. + + if (result == null) + { + return false; + } + bool isSlewing = result != string.Empty; - tl.LogMessage("Slewing Get", $"Result = {isSlewing}"); + LogMessage("Slewing Get", $"Result = {isSlewing}"); return isSlewing; } } public void SyncToAltAz(double azimuth, double altitude) { - tl.LogMessage("SyncToAltAz", "Not implemented"); - throw new ASCOM.MethodNotImplementedException("SyncToAltAz"); + LogMessage("SyncToAltAz", "Not implemented"); + throw new MethodNotImplementedException("SyncToAltAz"); } public void SyncToCoordinates(double rightAscension, double declination) { - tl.LogMessage("SyncToCoordinates", $"RA={rightAscension} Dec={declination}"); + LogMessage("SyncToCoordinates", $"RA={rightAscension} Dec={declination}"); CheckConnected("SyncToCoordinates"); - SharedResources.Lock(() => + _sharedResourcesWrapper.Lock(() => { TargetRightAscension = rightAscension; TargetDeclination = declination; @@ -1593,26 +1607,26 @@ namespace ASCOM.Meade.net public void SyncToTarget() { - tl.LogMessage("SyncToTarget", "Executing"); + LogMessage("SyncToTarget", "Executing"); CheckConnected("SyncToTarget"); - var result = SharedResources.SendString(":CM#"); + var result = _sharedResourcesWrapper.SendString(":CM#"); //:CM# Synchronizes the telescope's position with the currently selected database object's coordinates. //Returns: //LX200's - a "#" terminated string with the name of the object that was synced. - // Autostars & Autostar II - At static string: " M31 EX GAL MAG 3.5 SZ178.0'#" + // Autostars & Autostar II - A static string: " M31 EX GAL MAG 3.5 SZ178.0'#" if (result == string.Empty) - throw new ASCOM.InvalidOperationException("Unable to perform sync"); + throw new InvalidOperationException("Unable to perform sync"); } - private double _targetDeclination = INVALID_PARAMETER; + private double _targetDeclination = InvalidParameter; public double TargetDeclination { get { - if (_targetDeclination == INVALID_PARAMETER) - throw new ASCOM.InvalidOperationException("Target not set"); + if (_targetDeclination == InvalidParameter) + throw new InvalidOperationException("Target not set"); //var result = SerialPort.CommandTerminated(":Gd#", "#"); ////:Gd# Get Currently Selected Object/Target Declination @@ -1623,29 +1637,29 @@ namespace ASCOM.Meade.net //return targetDec; - tl.LogMessage("TargetDeclination Get", $"{_targetDeclination}"); + LogMessage("TargetDeclination Get", $"{_targetDeclination}"); return _targetDeclination; } set { - tl.LogMessage("TargetDeclination Set", $"{value}"); - - //todo implement low precision version of this. - if (value > 90) - throw new ASCOM.InvalidValueException("Declination cannot be greater than 90."); - - if (value < -90) - throw new ASCOM.InvalidValueException("Declination cannot be less than -90."); + LogMessage("TargetDeclination Set", $"{value}"); CheckConnected("TargetDeclination Set"); - var dms = utilities.DegreesToDMS(value, "*", ":", ":", 2); + //todo implement low precision version of this. + if (value > 90) + throw new InvalidValueException("Declination cannot be greater than 90."); + + if (value < -90) + throw new InvalidValueException("Declination cannot be less than -90."); + + var dms = _utilities.DegreesToDMS(value, "*", ":", ":", 2); var s = value < 0 ? string.Empty : "+"; var command = $":Sd{s}{dms}#"; - tl.LogMessage("TargetDeclination Set", $"{command}"); - var result = SharedResources.SendChar(command); + LogMessage("TargetDeclination Set", $"{command}"); + var result = _sharedResourcesWrapper.SendChar(command); //:SdsDD*MM# //Set target object declination to sDD*MM or sDD*MM:SS depending on the current precision setting //Returns: @@ -1654,20 +1668,20 @@ namespace ASCOM.Meade.net if (result == "0") { - throw new ASCOM.InvalidOperationException("Target declination invalid"); + throw new InvalidOperationException("Target declination invalid"); } _targetDeclination = value; } } - private double _targetRightAscension = INVALID_PARAMETER; + private double _targetRightAscension = InvalidParameter; public double TargetRightAscension { get { - if (_targetRightAscension == INVALID_PARAMETER) - throw new ASCOM.InvalidOperationException("Target not set"); + if (_targetRightAscension == InvalidParameter) + throw new InvalidOperationException("Target not set"); //var result = SerialPort.CommandTerminated(":Gr#", "#"); ////:Gr# Get current/target object RA @@ -1677,24 +1691,23 @@ namespace ASCOM.Meade.net //double targetRa = HmsToDouble(result); //return targetRa; - tl.LogMessage("TargetRightAscension Get", $"{_targetRightAscension}"); + LogMessage("TargetRightAscension Get", $"{_targetRightAscension}"); return _targetRightAscension; } set { - tl.LogMessage("TargetRightAscension Set", $"{value}"); + LogMessage("TargetRightAscension Set", $"{value}"); + CheckConnected("TargetRightAscension Set"); if (value < 0) throw new InvalidValueException("Right ascension value cannot be below 0"); if (value >= 24) throw new InvalidValueException("Right ascension value cannot be greater than 23:59:59"); - - CheckConnected("TargetRightAscension Set"); //todo implement the low precision version - var hms = utilities.HoursToHMS(value, ":", ":", ":", 2); - var response = SharedResources.SendChar($":Sr{hms}#"); + var hms = _utilities.HoursToHMS(value, ":", ":", ":", 2); + var response = _sharedResourcesWrapper.SendChar($":Sr{hms}#"); //:SrHH:MM.T# //:SrHH:MM:SS# //Set target object RA to HH:MM.T or HH: MM: SS depending on the current precision setting. @@ -1714,12 +1727,12 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("Tracking", $"Get - {_tracking}"); + LogMessage("Tracking", $"Get - {_tracking}"); return _tracking; } set { - tl.LogMessage($"Tracking Set", $"{value}"); + LogMessage($"Tracking Set", $"{value}"); _tracking = value; } } @@ -1742,23 +1755,23 @@ namespace ASCOM.Meade.net // return DriveRates.driveSidereal; //return DriveRates.driveKing; - tl.LogMessage("TrackingRate Get", $"{_trackingRate}"); + LogMessage("TrackingRate Get", $"{_trackingRate}"); return _trackingRate; } set { - tl.LogMessage("TrackingRate Set", $"{value}"); + LogMessage("TrackingRate Set", $"{value}"); CheckConnected("TrackingRate Set"); switch (value) { case DriveRates.driveSidereal: - SharedResources.SendBlind(":TQ#"); + _sharedResourcesWrapper.SendBlind(":TQ#"); //:TQ# Selects sidereal tracking rate //Returns: Nothing break; case DriveRates.driveLunar: - SharedResources.SendBlind(":TL#"); + _sharedResourcesWrapper.SendBlind(":TL#"); //:TL# Set Lunar Tracking Rage //Returns: Nothing break; @@ -1784,10 +1797,10 @@ namespace ASCOM.Meade.net get { ITrackingRates trackingRates = new TrackingRates(); - tl.LogMessage("TrackingRates", "Get - "); + LogMessage("TrackingRates", "Get - "); foreach (DriveRates driveRate in trackingRates) { - tl.LogMessage("TrackingRates", "Get - " + driveRate.ToString()); + LogMessage("TrackingRates", "Get - " + driveRate.ToString()); } return trackingRates; } @@ -1795,9 +1808,7 @@ namespace ASCOM.Meade.net private TimeSpan GetUtcCorrection() { - CheckConnected("GetUtcCorrection"); - - string utcOffSet = SharedResources.SendString(":GG#"); + string utcOffSet = _sharedResourcesWrapper.SendString(":GG#"); //:GG# Get UTC offset time //Returns: sHH# or sHH.H# //The number of decimal hours to add to local time to convert it to UTC. If the number is a whole number the @@ -1807,11 +1818,11 @@ namespace ASCOM.Meade.net return utcCorrection; } - private class TelescopeDateDetails + public class TelescopeDateDetails { - public string telescopeDate { get; set; } - public string telescopeTime { get; set; } - public TimeSpan utcCorrection { get; set; } + public string TelescopeDate { get; set; } + public string TelescopeTime { get; set; } + public TimeSpan UtcCorrection { get; set; } } public DateTime UTCDate @@ -1820,56 +1831,57 @@ namespace ASCOM.Meade.net { CheckConnected("UTCDate Get"); - tl.LogMessage("UTCDate", "Get started"); + LogMessage("UTCDate", "Get started"); - TelescopeDateDetails telescopeDateDetails = SharedResources.Lock(() => + TelescopeDateDetails telescopeDateDetails = _sharedResourcesWrapper.Lock(() => { TelescopeDateDetails tdd = new TelescopeDateDetails(); - tdd.telescopeDate = SharedResources.SendString(":GC#"); + tdd.TelescopeDate = _sharedResourcesWrapper.SendString(":GC#"); //:GC# Get current date. - //Returns: MM / DD / YY# + //Returns: MM/DD/YY# //The current local calendar date for the telescope. - tdd.telescopeTime = SharedResources.SendString(":GL#"); + tdd.TelescopeTime = _sharedResourcesWrapper.SendString(":GL#"); //:GL# Get Local Time in 24 hour format - //Returns: HH: MM: SS# + //Returns: HH:MM:SS# //The Local Time in 24 - hour Format - tdd.utcCorrection = GetUtcCorrection(); + tdd.UtcCorrection = GetUtcCorrection(); return tdd; }); - int month = telescopeDateDetails.telescopeDate.Substring(0, 2).ToInteger(); - int day = telescopeDateDetails.telescopeDate.Substring(3, 2).ToInteger(); - int year = telescopeDateDetails.telescopeDate.Substring(6, 2).ToInteger(); + int month = telescopeDateDetails.TelescopeDate.Substring(0, 2).ToInteger(); + int day = telescopeDateDetails.TelescopeDate.Substring(3, 2).ToInteger(); + int year = telescopeDateDetails.TelescopeDate.Substring(6, 2).ToInteger(); if (year < 2000) //todo fix this hack that will create a Y2K100 bug { year = year + 2000; } - int hour = telescopeDateDetails.telescopeTime.Substring(0, 2).ToInteger(); - int minute = telescopeDateDetails.telescopeTime.Substring(3, 2).ToInteger(); - int second = telescopeDateDetails.telescopeTime.Substring(6, 2).ToInteger(); + int hour = telescopeDateDetails.TelescopeTime.Substring(0, 2).ToInteger(); + int minute = telescopeDateDetails.TelescopeTime.Substring(3, 2).ToInteger(); + int second = telescopeDateDetails.TelescopeTime.Substring(6, 2).ToInteger(); var utcDate = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc) + - telescopeDateDetails.utcCorrection; + telescopeDateDetails.UtcCorrection; - tl.LogMessage("UTCDate", "Get - " + utcDate.ToString("MM/dd/yy HH:mm:ss")); + LogMessage("UTCDate", "Get - " + utcDate.ToString("MM/dd/yy HH:mm:ss")); return utcDate; } set { - tl.LogMessage("UTCDate", "Set - " + value.ToString("MM/dd/yy HH:mm:ss")); + LogMessage("UTCDate", "Set - " + value.ToString("MM/dd/yy HH:mm:ss")); CheckConnected("UTCDate Set"); - SharedResources.Lock(() => + _sharedResourcesWrapper.Lock(() => { var utcCorrection = GetUtcCorrection(); var localDateTime = value - utcCorrection; - var timeResult = SharedResources.SendChar($":SL{localDateTime:HH:mm:ss}#"); + string localStingCommand = $":SL{localDateTime:HH:mm:ss}#"; + var timeResult = _sharedResourcesWrapper.SendChar(localStingCommand); //:SLHH:MM:SS# //Set the local Time //Returns: @@ -1880,7 +1892,8 @@ namespace ASCOM.Meade.net throw new InvalidOperationException("Failed to set local time"); } - var dateResult = SharedResources.SendChar($":SC{localDateTime:MM/dd/yy}#"); + string localDateCommand = $":SC{localDateTime:MM/dd/yy}#"; + var dateResult = _sharedResourcesWrapper.SendChar(localDateCommand); //:SCMM/DD/YY# //Change Handbox Date to MM/DD/YY //Returns: @@ -1893,16 +1906,16 @@ namespace ASCOM.Meade.net } //throwing away these two strings which represent - SharedResources.ReadTerminated(); //Updating Planetary Data# - SharedResources.ReadTerminated(); // # + _sharedResourcesWrapper.ReadTerminated(); //Updating Planetary Data# + _sharedResourcesWrapper.ReadTerminated(); // # }); } } public void Unpark() { - tl.LogMessage("Unpark", "Not implemented"); - throw new ASCOM.MethodNotImplementedException("Unpark"); + LogMessage("Unpark", "Not implemented"); + throw new MethodNotImplementedException("Unpark"); } #endregion @@ -1921,18 +1934,18 @@ namespace ASCOM.Meade.net /// This is harmless if the driver is already registered/unregistered. /// /// If true, registers the driver, otherwise unregisters it. - private static void RegUnregASCOM(bool bRegister) + private static void RegUnregAscom(bool bRegister) { - using (var P = new ASCOM.Utilities.Profile()) + using (var p = new Profile()) { - P.DeviceType = "Telescope"; + p.DeviceType = "Telescope"; if (bRegister) { - P.Register(driverID, driverDescription); + p.Register(DriverId, DriverDescription); } else { - P.Unregister(driverID); + p.Unregister(DriverId); } } } @@ -1955,9 +1968,9 @@ namespace ASCOM.Meade.net /// This technique should mean that it is never necessary to manually register a driver with ASCOM. /// [ComRegisterFunction] - public static void RegisterASCOM(Type t) + public static void RegisterAscom(Type t) { - RegUnregASCOM(true); + RegUnregAscom(true); } /// @@ -1978,9 +1991,9 @@ namespace ASCOM.Meade.net /// This technique should mean that it is never necessary to manually unregister a driver from ASCOM. /// [ComUnregisterFunction] - public static void UnregisterASCOM(Type t) + public static void UnregisterAscom(Type t) { - RegUnregASCOM(false); + RegUnregAscom(false); } #endregion @@ -1988,14 +2001,7 @@ namespace ASCOM.Meade.net /// /// Returns true if there is a valid connection to the driver hardware /// - private bool IsConnected - { - get - { - // TODO check that the driver hardware connection exists and is connected to the hardware - return _connectedState; - } - } + private bool IsConnected { get; set; } /// /// Use this function to throw an exception if we aren't connected to the hardware @@ -2005,7 +2011,7 @@ namespace ASCOM.Meade.net { if (!IsConnected) { - throw new ASCOM.NotConnectedException(message); + throw new NotConnectedException($"Not connected to telescope when trying to execute: {message}"); } } @@ -2014,9 +2020,9 @@ namespace ASCOM.Meade.net /// internal void ReadProfile() { - var profileProperties = SharedResources.ReadProfile(); - tl.Enabled = profileProperties.TraceLogger; - comPort = profileProperties.ComPort; + var profileProperties = _sharedResourcesWrapper.ReadProfile(); + _tl.Enabled = profileProperties.TraceLogger; + _comPort = profileProperties.ComPort; } /// @@ -2025,10 +2031,10 @@ namespace ASCOM.Meade.net /// /// /// - internal static void LogMessage(string identifier, string message, params object[] args) + internal void LogMessage(string identifier, string message, params object[] args) { var msg = string.Format(message, args); - tl.LogMessage(identifier, msg); + _tl.LogMessage(identifier, msg); } #endregion } diff --git a/Meade.net.Telescope/packages.config b/Meade.net.Telescope/packages.config new file mode 100644 index 0000000..a842451 --- /dev/null +++ b/Meade.net.Telescope/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Meade.net.focuser/BootstrapAscomProfileStore.ps1 b/Meade.net.focuser/BootstrapAscomProfileStore.ps1 new file mode 100644 index 0000000..213c64d --- /dev/null +++ b/Meade.net.focuser/BootstrapAscomProfileStore.ps1 @@ -0,0 +1,36 @@ +<# +This script initializes a bare minimum set of registry entries required for ASCOM.Utilities.Profile to work +without throwing any exceptions. When building on a build server, or on a computer without the ASCOM Platform installed, +it may be useful to execute this script as a build step prior to running any unit tests, or calling any code that relies on +ASCOM.Utilities.Profile. The alternative is to install the ASCOM Platform on the build agent. + +NOTE: This script equires elevated permissions because it creates registry keys in the LocalMachine hive. +#> + +$wow = Test-Path HKLM:\SOFTWARE\Wow6432Node +if ($wow) + { + $root = "HKLM:\SOFTWARE\Wow6432Node" + } +else + { + $root = "HKLM:\SOFTWARE" + } +$ascomRoot = $root + "\ASCOM" + +if (Test-Path $ascomRoot) + { + <# Don't upset an already-existing ASCOM registry #> + exit + } + +<# Create the ASCOM root key and set it's ACL to allow all users read/write access #> +New-Item -Path $root -Name ASCOM –Force +$ascomAcl = Get-Acl $ascomRoot +$aclRule = New-Object System.Security.AccessControl.RegistryAccessRule ("Users","FullControl","Allow") +$ascomAcl.SetAccessRule($aclRule) +$ascomAcl | Set-Acl -Path $ascomRoot + +<# Now create the bare minimum keys required so that ASCOM.Utilities.Profile doesn't crash and burn #> +New-ItemProperty -Path $ascomRoot -Name PlatformVersion -Value "6.1" -PropertyType String –Force +New-ItemProperty -Path $ascomRoot -Name SerTraceFile -Value "C:\SerialTraceAuto.txt" -PropertyType String –Force diff --git a/Meade.net.focuser/Focuser.cs b/Meade.net.focuser/Focuser.cs index 75a6f18..bf3a891 100644 --- a/Meade.net.focuser/Focuser.cs +++ b/Meade.net.focuser/Focuser.cs @@ -1,45 +1,14 @@ -//tabs=4 -// -------------------------------------------------------------------------------- -// TODO fill in this information for your driver, then remove this line! -// -// ASCOM Focuser driver for Meade.net -// -// 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 Focuser 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 Focuser using System; -using System.Collections.Generic; using System.Diagnostics; -using System.Text; 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 System.Reflection; +using ASCOM.Meade.net.Wrapper; using ASCOM.Utilities.Interfaces; namespace ASCOM.Meade.net @@ -69,39 +38,26 @@ namespace ASCOM.Meade.net /// The DeviceID is used by ASCOM applications to load the driver at runtime. /// //internal static string driverID = "ASCOM.Meade.net.Focuser"; - internal static string driverID = Marshal.GenerateProgIdForType(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly string DriverId = Marshal.GenerateProgIdForType(MethodBase.GetCurrentMethod().DeclaringType); // 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 Generic"; + private static readonly string DriverDescription = "Meade Generic"; - 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 the connected state - /// - private bool connectedState; + private 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; + private readonly IUtil _utilities; /// /// Variable to hold the trace logger object (creates a diagnostic log file with information that you specify) /// - internal static TraceLogger tl; + internal static TraceLogger Tl; + + private readonly ISharedResourcesWrapper _sharedResourcesWrapper; /// /// Initializes a new instance of the class. @@ -109,16 +65,23 @@ namespace ASCOM.Meade.net /// public Focuser() { - tl = new TraceLogger("", "Meade.net.focusser"); + //todo move this out to IOC + _utilities = new Util(); //Initialise util object + _sharedResourcesWrapper = new SharedResourcesWrapper(); + + Initialise(); + } + + private void Initialise() + { + Tl = new TraceLogger("", "Meade.net.focusser"); + + Tl.LogMessage("Focuser", "Starting initialisation"); ReadProfile(); // Read device configuration from the ASCOM Profile store - tl.LogMessage("Focuser", "Starting initialisation"); + IsConnected = false; // Initialise connected to false - connectedState = false; // Initialise connected to false - utilities = new Util(); //Initialise util object - astroUtilities = new AstroUtils(); // Initialise astro utilities object - - tl.LogMessage("Focuser", "Completed initialisation"); + Tl.LogMessage("Focuser", "Completed initialisation"); } @@ -136,17 +99,17 @@ namespace ASCOM.Meade.net /// public void SetupDialog() { - tl.LogMessage("SetupDialog", "Opening setup dialog"); - SharedResources.SetupDialog(); + Tl.LogMessage("SetupDialog", "Opening setup dialog"); + _sharedResourcesWrapper.SetupDialog(); ReadProfile(); - tl.LogMessage("SetupDialog", "complete"); + Tl.LogMessage("SetupDialog", "complete"); } public ArrayList SupportedActions { get { - tl.LogMessage("SupportedActions Get", "Returning empty arraylist"); + Tl.LogMessage("SupportedActions Get", "Returning empty arraylist"); return new ArrayList(); } } @@ -154,7 +117,7 @@ namespace ASCOM.Meade.net 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"); + throw new ActionNotImplementedException("Action " + actionName + " is not implemented by this driver"); } public void CommandBlind(string command, bool raw) @@ -162,7 +125,7 @@ namespace ASCOM.Meade.net CheckConnected("CommandBlind"); // Call CommandString and return as soon as it finishes //this.CommandString(command, raw); - SharedResources.SendBlind(command); + _sharedResourcesWrapper.SendBlind(command); // or //throw new ASCOM.MethodNotImplementedException("CommandBlind"); // DO NOT have both these sections! One or the other @@ -174,7 +137,7 @@ namespace ASCOM.Meade.net //string ret = CommandString(command, raw); // TODO decode the return string and return true or false // or - throw new ASCOM.MethodNotImplementedException("CommandBool"); + throw new MethodNotImplementedException("CommandBool"); // DO NOT have both these sections! One or the other } @@ -184,21 +147,17 @@ namespace ASCOM.Meade.net // 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 - return SharedResources.SendString(command); + return _sharedResourcesWrapper.SendString(command); - throw new ASCOM.MethodNotImplementedException("CommandString"); + throw new MethodNotImplementedException("CommandString"); } public void Dispose() { // Clean up the tracelogger and util objects - tl.Enabled = false; - tl.Dispose(); - tl = null; - utilities.Dispose(); - utilities = null; - astroUtilities.Dispose(); - astroUtilities = null; + Tl.Enabled = false; + Tl.Dispose(); + Tl = null; } public bool Connected @@ -210,7 +169,7 @@ namespace ASCOM.Meade.net } set { - tl.LogMessage("Connected", "Set {0}", value); + Tl.LogMessage("Connected", "Set {0}", value); if (value == IsConnected) return; @@ -218,39 +177,39 @@ namespace ASCOM.Meade.net { try { - SharedResources.Connect("Serial"); + _sharedResourcesWrapper.Connect("Serial"); try { SelectSite(1); SetLongFormat(true); - connectedState = true; + IsConnected = true; } catch (Exception) { - SharedResources.Disconnect("Serial"); + _sharedResourcesWrapper.Disconnect("Serial"); throw; } } catch (Exception ex) { - LogMessage("Connected Set", "Error connecting to port {0} - {1}", comPort, ex.Message); + LogMessage("Connected Set", "Error connecting to port {0} - {1}", _comPort, ex.Message); } } else { - LogMessage("Connected Set", "Disconnecting from port {0}", comPort); - SharedResources.Disconnect("Serial"); - connectedState = false; + LogMessage("Connected Set", "Disconnecting from port {0}", _comPort); + _sharedResourcesWrapper.Disconnect("Serial"); + IsConnected = false; } } } private void SetLongFormat(bool setLongFormat) { - SharedResources.Lock(() => + _sharedResourcesWrapper.Lock(() => { - var result = SharedResources.SendString(":GZ#"); + var result = _sharedResourcesWrapper.SendString(":GZ#"); //:GZ# Get telescope azimuth //Returns: DDD*MM#T or DDD*MM’SS# //The current telescope Azimuth depending on the selected precision. @@ -259,8 +218,8 @@ namespace ASCOM.Meade.net if (isLongFormat != setLongFormat) { - utilities.WaitForMilliseconds(500); - SharedResources.SendBlind(":U#"); + _utilities.WaitForMilliseconds(500); + _sharedResourcesWrapper.SendBlind(":U#"); //:U# Toggle between low/hi precision positions //Low - RA displays and messages HH:MM.T sDD*MM //High - Dec / Az / El displays and messages HH:MM: SS sDD*MM:SS @@ -271,7 +230,7 @@ namespace ASCOM.Meade.net private void SelectSite(int site) { - SharedResources.SendBlind($":W{site}#"); + _sharedResourcesWrapper.SendBlind($":W{site}#"); //:W# //Set current site to, an ASCII digit in the range 1..4 //Returns: Nothing @@ -282,8 +241,8 @@ namespace ASCOM.Meade.net // TODO customise this device description get { - tl.LogMessage("Description Get", driverDescription); - return driverDescription; + Tl.LogMessage("Description Get", DriverDescription); + return DriverDescription; } } @@ -291,10 +250,10 @@ namespace ASCOM.Meade.net { get { - Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; + Version version = Assembly.GetExecutingAssembly().GetName().Version; // TODO customise this driver description string driverInfo = "Information about the driver itself. Version: " + String.Format(CultureInfo.InvariantCulture, "{0}.{1}", version.Major, version.Minor); - tl.LogMessage("DriverInfo Get", driverInfo); + Tl.LogMessage("DriverInfo Get", driverInfo); return driverInfo; } } @@ -303,9 +262,9 @@ namespace ASCOM.Meade.net { get { - Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; + Version version = Assembly.GetExecutingAssembly().GetName().Version; string driverVersion = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", version.Major, version.Minor); - tl.LogMessage("DriverVersion Get", driverVersion); + Tl.LogMessage("DriverVersion Get", driverVersion); return driverVersion; } } @@ -325,8 +284,8 @@ namespace ASCOM.Meade.net get { //string name = "Short driver name - please customise"; - string name = driverDescription; - tl.LogMessage("Name Get", name); + string name = DriverDescription; + Tl.LogMessage("Name Get", name); return name; } } @@ -339,14 +298,14 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("Absolute Get", false.ToString()); + Tl.LogMessage("Absolute Get", false.ToString()); return false; // This is a relative focuser } } public void Halt() { - tl.LogMessage("Halt", "Halting"); + Tl.LogMessage("Halt", "Halting"); CheckConnected("Halt"); @@ -354,11 +313,11 @@ namespace ASCOM.Meade.net Stopwatch stopwatch = Stopwatch.StartNew(); while (stopwatch.ElapsedMilliseconds < 1000) { - SharedResources.SendBlind(":FQ#"); + _sharedResourcesWrapper.SendBlind(":FQ#"); //:FQ# Halt Focuser Motion //Returns: Nothing - utilities.WaitForMilliseconds(250); + _utilities.WaitForMilliseconds(250); } } @@ -366,7 +325,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("IsMoving Get", false.ToString()); + Tl.LogMessage("IsMoving Get", false.ToString()); return false; // This focuser always moves instantaneously so no need for IsMoving ever to be True } } @@ -375,13 +334,13 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("Link Get", this.Connected.ToString()); - return this.Connected; // Direct function to the connected method, the Link method is just here for backwards compatibility + Tl.LogMessage("Link Get", Connected.ToString()); + return Connected; // Direct function to the connected method, the Link method is just here for backwards compatibility } set { - tl.LogMessage("Link Set", value.ToString()); - this.Connected = value; // Direct function to the connected method, the Link method is just here for backwards compatibility + Tl.LogMessage("Link Set", value.ToString()); + Connected = value; // Direct function to the connected method, the Link method is just here for backwards compatibility } } @@ -390,7 +349,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("MaxIncrement Get", _maxIncrement.ToString()); + Tl.LogMessage("MaxIncrement Get", _maxIncrement.ToString()); return _maxIncrement; // Maximum change in one move } } @@ -400,45 +359,45 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("MaxStep Get", _maxStep.ToString()); + Tl.LogMessage("MaxStep Get", _maxStep.ToString()); return _maxStep; } } - public void Move(int Position) + public void Move(int position) { - tl.LogMessage("Move", Position.ToString()); + Tl.LogMessage("Move", position.ToString()); CheckConnected("Move"); //todo implement backlash compensation //todo implement direction reverse //todo implement dynamic braking - if (Position < -MaxIncrement || Position > MaxIncrement) + if (position < -MaxIncrement || position > MaxIncrement) { - throw new ASCOM.InvalidValueException($"position out of range {-MaxIncrement} < {Position} < {MaxIncrement}"); + throw new InvalidValueException($"position out of range {-MaxIncrement} < {position} < {MaxIncrement}"); } - if (Position == 0) + if (position == 0) return; - if (Position > 0) + if (position > 0) { //desired move direction is out - MoveFocuser(true, Math.Abs(Position)); + MoveFocuser(true, Math.Abs(position)); } else { //desired move direction is in - MoveFocuser(false, Math.Abs(Position)); + MoveFocuser(false, Math.Abs(position)); } } private void MoveFocuser(bool directionOut, int steps) { - SharedResources.Lock(() => + _sharedResourcesWrapper.Lock(() => { - //SharedResources.SendBlind(":FF#"); + //_sharedResourcesWrapper.SendBlind(":FF#"); //:FF# Set Focus speed to fastest setting //Returns: Nothing @@ -448,44 +407,37 @@ namespace ASCOM.Meade.net //:F# Autostar, Autostar II – set focuser speed to where is an ASCII digit 1..4 //Returns: Nothing //All others – Not Supported - utilities.WaitForMilliseconds(100); + _utilities.WaitForMilliseconds(100); //A Single focus command sometimes gets lost on the #909, so sending lots of them solves the issue. Stopwatch stopwatch = Stopwatch.StartNew(); while (stopwatch.ElapsedMilliseconds < steps) { - SharedResources.SendBlind(directionOut ? ":F+#" : ":F-#"); + _sharedResourcesWrapper.SendBlind(directionOut ? ":F+#" : ":F-#"); //:F+# Start Focuser moving inward (toward objective) //Returns: None //:F-# Start Focuser moving outward (away from objective) //Returns: None - utilities.WaitForMilliseconds(250); + _utilities.WaitForMilliseconds(250); } Halt(); //This gives the focuser time to physically stop. - utilities.WaitForMilliseconds(1000); + _utilities.WaitForMilliseconds(1000); }); } - public int Position - { - get - { - throw new ASCOM.PropertyNotImplementedException("Position", false); - //return focuserPosition; // Return the focuser position - } - } + public int Position => throw new PropertyNotImplementedException("Position", false); public double StepSize { get { - tl.LogMessage("StepSize Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("StepSize", false); + Tl.LogMessage("StepSize Get", "Not implemented"); + throw new PropertyNotImplementedException("StepSize", false); } } @@ -493,13 +445,13 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("TempComp Get", false.ToString()); + Tl.LogMessage("TempComp Get", false.ToString()); return false; } set { - tl.LogMessage("TempComp Set", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("TempComp", false); + Tl.LogMessage("TempComp Set", "Not implemented"); + throw new PropertyNotImplementedException("TempComp", false); } } @@ -507,7 +459,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("TempCompAvailable Get", false.ToString()); + Tl.LogMessage("TempCompAvailable Get", false.ToString()); return false; // Temperature compensation is not available in this driver } } @@ -516,8 +468,8 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("Temperature Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("Temperature", false); + Tl.LogMessage("Temperature Get", "Not implemented"); + throw new PropertyNotImplementedException("Temperature", false); } } @@ -537,18 +489,18 @@ namespace ASCOM.Meade.net /// This is harmless if the driver is already registered/unregistered. /// /// If true, registers the driver, otherwise unregisters it. - private static void RegUnregASCOM(bool bRegister) + private static void RegUnregAscom(bool bRegister) { - using (var P = new ASCOM.Utilities.Profile()) + using (var p = new Profile()) { - P.DeviceType = "Focuser"; + p.DeviceType = "Focuser"; if (bRegister) { - P.Register(driverID, driverDescription); + p.Register(DriverId, DriverDescription); } else { - P.Unregister(driverID); + p.Unregister(DriverId); } } } @@ -571,9 +523,9 @@ namespace ASCOM.Meade.net /// This technique should mean that it is never necessary to manually register a driver with ASCOM. /// [ComRegisterFunction] - public static void RegisterASCOM(Type t) + public static void RegisterAscom(Type t) { - RegUnregASCOM(true); + RegUnregAscom(true); } /// @@ -594,9 +546,9 @@ namespace ASCOM.Meade.net /// This technique should mean that it is never necessary to manually unregister a driver from ASCOM. /// [ComUnregisterFunction] - public static void UnregisterASCOM(Type t) + public static void UnregisterAscom(Type t) { - RegUnregASCOM(false); + RegUnregAscom(false); } #endregion @@ -604,14 +556,7 @@ namespace ASCOM.Meade.net /// /// Returns true if there is a valid connection to the driver hardware /// - private bool IsConnected - { - get - { - // TODO check that the driver hardware connection exists and is connected to the hardware - return connectedState; - } - } + private bool IsConnected { get; set; } /// /// Use this function to throw an exception if we aren't connected to the hardware @@ -621,7 +566,7 @@ namespace ASCOM.Meade.net { if (!IsConnected) { - throw new ASCOM.NotConnectedException(message); + throw new NotConnectedException(message); } } @@ -630,9 +575,9 @@ namespace ASCOM.Meade.net /// internal void ReadProfile() { - var profileProperties = SharedResources.ReadProfile(); - tl.Enabled = profileProperties.TraceLogger; - comPort = profileProperties.ComPort; + var profileProperties = _sharedResourcesWrapper.ReadProfile(); + Tl.Enabled = profileProperties.TraceLogger; + _comPort = profileProperties.ComPort; } /// @@ -644,7 +589,7 @@ namespace ASCOM.Meade.net internal static void LogMessage(string identifier, string message, params object[] args) { var msg = string.Format(message, args); - tl.LogMessage(identifier, msg); + Tl.LogMessage(identifier, msg); } #endregion } diff --git a/Meade.net.focuser/Meade.net.focuser.csproj b/Meade.net.focuser/Meade.net.focuser.csproj index bafde48..d161efc 100644 --- a/Meade.net.focuser/Meade.net.focuser.csproj +++ b/Meade.net.focuser/Meade.net.focuser.csproj @@ -80,14 +80,39 @@ MinimumRecommendedRules.ruleset - - - - - - - - + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Astrometry.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Attributes.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Cache.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Controls.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DeviceInterfaces.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DriverAccess.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Exceptions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Internal.Extensions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.SettingsProvider.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.Video.dll + @@ -124,6 +149,8 @@ + + SettingsSingleFileGenerator Settings.Designer.cs diff --git a/Meade.net.focuser/Meade.net.focuser.v3.ncrunchproject b/Meade.net.focuser/Meade.net.focuser.v3.ncrunchproject new file mode 100644 index 0000000..54c2f06 --- /dev/null +++ b/Meade.net.focuser/Meade.net.focuser.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + x86 + + \ No newline at end of file diff --git a/Meade.net.focuser/Properties/AssemblyInfo.cs b/Meade.net.focuser/Properties/AssemblyInfo.cs index d74c566..46c7ed0 100644 --- a/Meade.net.focuser/Properties/AssemblyInfo.cs +++ b/Meade.net.focuser/Properties/AssemblyInfo.cs @@ -1,5 +1,4 @@ using System.Reflection; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -35,5 +34,5 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: // // TODO - Set your driver's version here -[assembly: AssemblyVersion("0.7.0.0")] -[assembly: AssemblyFileVersion("0.7.0.0")] +[assembly: AssemblyVersion("0.0.0.0")] +[assembly: AssemblyFileVersion("0.0.0.0")] diff --git a/Meade.net.focuser/packages.config b/Meade.net.focuser/packages.config new file mode 100644 index 0000000..a842451 --- /dev/null +++ b/Meade.net.focuser/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Meade.net.sln b/Meade.net.sln index 96aacec..a77a62d 100644 --- a/Meade.net.sln +++ b/Meade.net.sln @@ -21,6 +21,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AstroMath.UnitTests", "Astr EndProject Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Meade.net.Setup", "Meade.net.Setup\Meade.net.Setup.wixproj", "{8EEB5C25-8394-4257-8E57-CDED47CB6F1B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Meade.net.Telescope.UnitTests", "Meade.net.Telescope.UnitTests\Meade.net.Telescope.UnitTests.csproj", "{B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -106,6 +108,18 @@ Global {8EEB5C25-8394-4257-8E57-CDED47CB6F1B}.Release|x64.ActiveCfg = Release|x86 {8EEB5C25-8394-4257-8E57-CDED47CB6F1B}.Release|x86.ActiveCfg = Release|x86 {8EEB5C25-8394-4257-8E57-CDED47CB6F1B}.Release|x86.Build.0 = Release|x86 + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Debug|x64.ActiveCfg = Debug|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Debug|x64.Build.0 = Debug|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Debug|x86.ActiveCfg = Debug|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Debug|x86.Build.0 = Debug|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Release|Any CPU.Build.0 = Release|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Release|x64.ActiveCfg = Release|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Release|x64.Build.0 = Release|Any CPU + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Release|x86.ActiveCfg = Release|x86 + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -114,6 +128,7 @@ Global {D5207217-61C7-4E94-8097-91DBACE57D2A} = {BF650D97-AF98-4638-9C55-21311C6D88DA} {AABC96B8-C462-4B3A-9B5F-2929E3CB7A49} = {BF650D97-AF98-4638-9C55-21311C6D88DA} {AD4959DD-33D7-4C3F-8DB0-7361D8E74A95} = {0958D817-269C-44BE-BEFB-F3E6A409DE91} + {B7EEEEFD-5BFF-443D-981C-7B8AB5DFDE33} = {0958D817-269C-44BE-BEFB-F3E6A409DE91} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {3C0509DC-C7F5-48DC-920D-DCFD9C879BD2} diff --git a/Meade.net.v3.ncrunchsolution b/Meade.net.v3.ncrunchsolution new file mode 100644 index 0000000..e4047c2 --- /dev/null +++ b/Meade.net.v3.ncrunchsolution @@ -0,0 +1,7 @@ + + + True + True + True + + \ No newline at end of file diff --git a/Meade.net.v3.ncrunchsolution.user b/Meade.net.v3.ncrunchsolution.user new file mode 100644 index 0000000..24ce899 --- /dev/null +++ b/Meade.net.v3.ncrunchsolution.user @@ -0,0 +1,16 @@ + + + True + Run all tests automatically [Global] + False + 25 + + false + false + true + true + false + + 451 + + \ No newline at end of file diff --git a/Meade.net/BootstrapAscomProfileStore.ps1 b/Meade.net/BootstrapAscomProfileStore.ps1 new file mode 100644 index 0000000..213c64d --- /dev/null +++ b/Meade.net/BootstrapAscomProfileStore.ps1 @@ -0,0 +1,36 @@ +<# +This script initializes a bare minimum set of registry entries required for ASCOM.Utilities.Profile to work +without throwing any exceptions. When building on a build server, or on a computer without the ASCOM Platform installed, +it may be useful to execute this script as a build step prior to running any unit tests, or calling any code that relies on +ASCOM.Utilities.Profile. The alternative is to install the ASCOM Platform on the build agent. + +NOTE: This script equires elevated permissions because it creates registry keys in the LocalMachine hive. +#> + +$wow = Test-Path HKLM:\SOFTWARE\Wow6432Node +if ($wow) + { + $root = "HKLM:\SOFTWARE\Wow6432Node" + } +else + { + $root = "HKLM:\SOFTWARE" + } +$ascomRoot = $root + "\ASCOM" + +if (Test-Path $ascomRoot) + { + <# Don't upset an already-existing ASCOM registry #> + exit + } + +<# Create the ASCOM root key and set it's ACL to allow all users read/write access #> +New-Item -Path $root -Name ASCOM –Force +$ascomAcl = Get-Acl $ascomRoot +$aclRule = New-Object System.Security.AccessControl.RegistryAccessRule ("Users","FullControl","Allow") +$ascomAcl.SetAccessRule($aclRule) +$ascomAcl | Set-Acl -Path $ascomRoot + +<# Now create the bare minimum keys required so that ASCOM.Utilities.Profile doesn't crash and burn #> +New-ItemProperty -Path $ascomRoot -Name PlatformVersion -Value "6.1" -PropertyType String –Force +New-ItemProperty -Path $ascomRoot -Name SerTraceFile -Value "C:\SerialTraceAuto.txt" -PropertyType String –Force diff --git a/Meade.net/ClassFactory.cs b/Meade.net/ClassFactory.cs index 1626f5c..431e2d0 100644 --- a/Meade.net/ClassFactory.cs +++ b/Meade.net/ClassFactory.cs @@ -33,43 +33,43 @@ namespace ASCOM.Meade.net #region Access to ole32.dll functions for class factories // Define two common GUID objects for public usage. - public static Guid IID_IUnknown = new Guid("{00000000-0000-0000-C000-000000000046}"); - public static Guid IID_IDispatch = new Guid("{00020400-0000-0000-C000-000000000046}"); + private static readonly Guid _iidIUnknown = new Guid("{00000000-0000-0000-C000-000000000046}"); + private static readonly Guid _iidIDispatch = new Guid("{00020400-0000-0000-C000-000000000046}"); [Flags] - enum CLSCTX : uint + enum Clsctx : uint { - CLSCTX_INPROC_SERVER = 0x1, - CLSCTX_INPROC_HANDLER = 0x2, - CLSCTX_LOCAL_SERVER = 0x4, - CLSCTX_INPROC_SERVER16 = 0x8, - CLSCTX_REMOTE_SERVER = 0x10, - CLSCTX_INPROC_HANDLER16 = 0x20, - CLSCTX_RESERVED1 = 0x40, - CLSCTX_RESERVED2 = 0x80, - CLSCTX_RESERVED3 = 0x100, - CLSCTX_RESERVED4 = 0x200, - CLSCTX_NO_CODE_DOWNLOAD = 0x400, - CLSCTX_RESERVED5 = 0x800, - CLSCTX_NO_CUSTOM_MARSHAL = 0x1000, - CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000, - CLSCTX_NO_FAILURE_LOG = 0x4000, - CLSCTX_DISABLE_AAA = 0x8000, - CLSCTX_ENABLE_AAA = 0x10000, - CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000, - CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, - CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, - CLSCTX_ALL = CLSCTX_SERVER | CLSCTX_INPROC_HANDLER + ClsctxInprocServer = 0x1, + ClsctxInprocHandler = 0x2, + ClsctxLocalServer = 0x4, + ClsctxInprocServer16 = 0x8, + ClsctxRemoteServer = 0x10, + ClsctxInprocHandler16 = 0x20, + ClsctxReserved1 = 0x40, + ClsctxReserved2 = 0x80, + ClsctxReserved3 = 0x100, + ClsctxReserved4 = 0x200, + ClsctxNoCodeDownload = 0x400, + ClsctxReserved5 = 0x800, + ClsctxNoCustomMarshal = 0x1000, + ClsctxEnableCodeDownload = 0x2000, + ClsctxNoFailureLog = 0x4000, + ClsctxDisableAaa = 0x8000, + ClsctxEnableAaa = 0x10000, + ClsctxFromDefaultContext = 0x20000, + ClsctxInproc = ClsctxInprocServer | ClsctxInprocHandler, + ClsctxServer = ClsctxInprocServer | ClsctxLocalServer | ClsctxRemoteServer, + ClsctxAll = ClsctxServer | ClsctxInprocHandler } [Flags] - enum REGCLS : uint + enum Regcls : uint { - REGCLS_SINGLEUSE = 0, - REGCLS_MULTIPLEUSE = 1, - REGCLS_MULTI_SEPARATE = 2, - REGCLS_SUSPENDED = 4, - REGCLS_SURROGATE = 8 + RegclsSingleuse = 0, + RegclsMultipleuse = 1, + RegclsMultiSeparate = 2, + RegclsSuspended = 4, + RegclsSurrogate = 8 } // // CoRegisterClassObject() is used to register a Class Factory @@ -109,70 +109,60 @@ namespace ASCOM.Meade.net #region Constructor and Private ClassFactory Data - protected Type m_ClassType; - protected Guid m_ClassId; - protected ArrayList m_InterfaceTypes; - protected uint m_ClassContext; - protected uint m_Flags; - protected UInt32 m_locked = 0; - protected uint m_Cookie; - protected string m_progid; + private readonly Type _mClassType; + private Guid _mClassId; + private readonly ArrayList _mInterfaceTypes; + private UInt32 _mLocked = 0; + private uint _mCookie; + private readonly string _mProgid; public ClassFactory(Type type) { if (type == null) throw new ArgumentNullException("type"); - m_ClassType = type; + _mClassType = type; //PWGS Get the ProgID from the MetaData - m_progid = Marshal.GenerateProgIdForType(type); - m_ClassId = Marshal.GenerateGuidForType(type); // Should be nailed down by [Guid(...)] - m_ClassContext = (uint)CLSCTX.CLSCTX_LOCAL_SERVER; // Default - m_Flags = (uint)REGCLS.REGCLS_MULTIPLEUSE | // Default - (uint)REGCLS.REGCLS_SUSPENDED; - m_InterfaceTypes = new ArrayList(); + _mProgid = Marshal.GenerateProgIdForType(type); + _mClassId = Marshal.GenerateGuidForType(type); // Should be nailed down by [Guid(...)] + ClassContext = (uint)Clsctx.ClsctxLocalServer; // Default + Flags = (uint)Regcls.RegclsMultipleuse | // Default + (uint)Regcls.RegclsSuspended; + _mInterfaceTypes = new ArrayList(); foreach (Type T in type.GetInterfaces()) // Save all of the implemented interfaces - m_InterfaceTypes.Add(T); + _mInterfaceTypes.Add(T); } #endregion #region Common ClassFactory Methods - public uint ClassContext - { - get { return m_ClassContext; } - set { m_ClassContext = value; } - } + public uint ClassContext { get; } public Guid ClassId { - get { return m_ClassId; } - set { m_ClassId = value; } + get => _mClassId; + set => _mClassId = value; } - public uint Flags - { - get { return m_Flags; } - set { m_Flags = value; } - } + public uint Flags { get; } public bool RegisterClassObject() { // Register the class factory int i = CoRegisterClassObject ( - ref m_ClassId, + ref _mClassId, this, - m_ClassContext, - m_Flags, - out m_Cookie + ClassContext, + Flags, + out _mCookie ); return (i == 0); } public bool RevokeClassObject() { - int i = CoRevokeClassObject(m_Cookie); + int i = CoRevokeClassObject(_mCookie); return (i == 0); } @@ -201,25 +191,25 @@ namespace ASCOM.Meade.net // // Handle specific requests for implemented interfaces // - foreach (Type iType in m_InterfaceTypes) + foreach (Type iType in _mInterfaceTypes) { if (riid == Marshal.GenerateGuidForType(iType)) { - ppvObject = Marshal.GetComInterfaceForObject(Activator.CreateInstance(m_ClassType), iType); + ppvObject = Marshal.GetComInterfaceForObject(Activator.CreateInstance(_mClassType), iType); return; } } // // Handle requests for IDispatch or IUnknown on the class // - if (riid == IID_IDispatch) + if (riid == _iidIDispatch) { - ppvObject = Marshal.GetIDispatchForObject(Activator.CreateInstance(m_ClassType)); + ppvObject = Marshal.GetIDispatchForObject(Activator.CreateInstance(_mClassType)); return; } - else if (riid == IID_IUnknown) + else if (riid == _iidIUnknown) { - ppvObject = Marshal.GetIUnknownForObject(Activator.CreateInstance(m_ClassType)); + ppvObject = Marshal.GetIUnknownForObject(Activator.CreateInstance(_mClassType)); } else { diff --git a/Meade.net/GarbageCollection.cs b/Meade.net/GarbageCollection.cs index 99aba52..f6d5e82 100644 --- a/Meade.net/GarbageCollection.cs +++ b/Meade.net/GarbageCollection.cs @@ -8,35 +8,35 @@ namespace ASCOM.Meade.net /// class GarbageCollection { - protected bool m_bContinueThread; - protected bool m_GCWatchStopped; - protected int m_iInterval; - protected ManualResetEvent m_EventThreadEnded; + private bool _mbContinueThread; + private bool _mGcWatchStopped; + private readonly int _miInterval; + private readonly ManualResetEvent _mEventThreadEnded; public GarbageCollection(int iInterval) { - m_bContinueThread = true; - m_GCWatchStopped = false; - m_iInterval = iInterval; - m_EventThreadEnded = new ManualResetEvent(false); + _mbContinueThread = true; + _mGcWatchStopped = false; + _miInterval = iInterval; + _mEventThreadEnded = new ManualResetEvent(false); } - public void GCWatch() + public void GcWatch() { // Pause for a moment to provide a delay to make threads more apparent. while (ContinueThread()) { GC.Collect(); - Thread.Sleep(m_iInterval); + Thread.Sleep(_miInterval); } - m_EventThreadEnded.Set(); + _mEventThreadEnded.Set(); } protected bool ContinueThread() { lock (this) { - return m_bContinueThread; + return _mbContinueThread; } } @@ -44,14 +44,14 @@ namespace ASCOM.Meade.net { lock (this) { - m_bContinueThread = false; + _mbContinueThread = false; } } public void WaitForThreadToStop() { - m_EventThreadEnded.WaitOne(); - m_EventThreadEnded.Reset(); + _mEventThreadEnded.WaitOne(); + _mEventThreadEnded.Reset(); } } } diff --git a/Meade.net/LocalServer.cs b/Meade.net/LocalServer.cs index a4fc2c2..ddafa39 100644 --- a/Meade.net/LocalServer.cs +++ b/Meade.net/LocalServer.cs @@ -15,17 +15,14 @@ using System; using System.IO; using System.Windows.Forms; -using System.Drawing; using System.Collections; using System.Runtime.InteropServices; using System.Reflection; using ASCOM.Utilities; using Microsoft.Win32; -using System.Text; using System.Threading; using System.Security.Principal; using System.Diagnostics; -using ASCOM; namespace ASCOM.Meade.net { @@ -34,52 +31,52 @@ namespace ASCOM.Meade.net #region Access to kernel32.dll, user32.dll, and ole32.dll functions [Flags] - enum CLSCTX : uint + enum Clsctx : uint { - CLSCTX_INPROC_SERVER = 0x1, - CLSCTX_INPROC_HANDLER = 0x2, - CLSCTX_LOCAL_SERVER = 0x4, - CLSCTX_INPROC_SERVER16 = 0x8, - CLSCTX_REMOTE_SERVER = 0x10, - CLSCTX_INPROC_HANDLER16 = 0x20, - CLSCTX_RESERVED1 = 0x40, - CLSCTX_RESERVED2 = 0x80, - CLSCTX_RESERVED3 = 0x100, - CLSCTX_RESERVED4 = 0x200, - CLSCTX_NO_CODE_DOWNLOAD = 0x400, - CLSCTX_RESERVED5 = 0x800, - CLSCTX_NO_CUSTOM_MARSHAL = 0x1000, - CLSCTX_ENABLE_CODE_DOWNLOAD = 0x2000, - CLSCTX_NO_FAILURE_LOG = 0x4000, - CLSCTX_DISABLE_AAA = 0x8000, - CLSCTX_ENABLE_AAA = 0x10000, - CLSCTX_FROM_DEFAULT_CONTEXT = 0x20000, - CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, - CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, - CLSCTX_ALL = CLSCTX_SERVER | CLSCTX_INPROC_HANDLER + ClsctxInprocServer = 0x1, + ClsctxInprocHandler = 0x2, + ClsctxLocalServer = 0x4, + ClsctxInprocServer16 = 0x8, + ClsctxRemoteServer = 0x10, + ClsctxInprocHandler16 = 0x20, + ClsctxReserved1 = 0x40, + ClsctxReserved2 = 0x80, + ClsctxReserved3 = 0x100, + ClsctxReserved4 = 0x200, + ClsctxNoCodeDownload = 0x400, + ClsctxReserved5 = 0x800, + ClsctxNoCustomMarshal = 0x1000, + ClsctxEnableCodeDownload = 0x2000, + ClsctxNoFailureLog = 0x4000, + ClsctxDisableAaa = 0x8000, + ClsctxEnableAaa = 0x10000, + ClsctxFromDefaultContext = 0x20000, + ClsctxInproc = ClsctxInprocServer | ClsctxInprocHandler, + ClsctxServer = ClsctxInprocServer | ClsctxLocalServer | ClsctxRemoteServer, + ClsctxAll = ClsctxServer | ClsctxInprocHandler } [Flags] - enum COINIT : uint + enum Coinit : uint { /// Initializes the thread for multi-threaded object concurrency. - COINIT_MULTITHREADED = 0x0, + CoinitMultithreaded = 0x0, /// Initializes the thread for apartment-threaded object concurrency. - COINIT_APARTMENTTHREADED = 0x2, + CoinitApartmentthreaded = 0x2, /// Disables DDE for Ole1 support. - COINIT_DISABLE_OLE1DDE = 0x4, + CoinitDisableOle1Dde = 0x4, /// Trades memory for speed. - COINIT_SPEED_OVER_MEMORY = 0x8 + CoinitSpeedOverMemory = 0x8 } [Flags] - enum REGCLS : uint + enum Regcls : uint { - REGCLS_SINGLEUSE = 0, - REGCLS_MULTIPLEUSE = 1, - REGCLS_MULTI_SEPARATE = 2, - REGCLS_SUSPENDED = 4, - REGCLS_SURROGATE = 8 + RegclsSingleuse = 0, + RegclsMultipleuse = 1, + RegclsMultiSeparate = 2, + RegclsSuspended = 4, + RegclsSurrogate = 8 } @@ -97,7 +94,7 @@ namespace ASCOM.Meade.net // We will need this API to post a WM_QUIT message to the main // thread in order to terminate this application. [DllImport("user32.dll")] - static extern bool PostThreadMessage(uint idThread, uint Msg, UIntPtr wParam, + static extern bool PostThreadMessage(uint idThread, uint msg, UIntPtr wParam, IntPtr lParam); // GetCurrentThreadId() allows us to obtain the thread id of the @@ -108,21 +105,21 @@ namespace ASCOM.Meade.net #endregion #region Private Data - private static int objsInUse; // Keeps a count on the total number of objects alive. - private static int serverLocks; // Keeps a lock count on this application. - private static frmMain s_MainForm = null; // Reference to our main form - private static ArrayList s_ComObjectAssys; // Dynamically loaded assemblies containing served COM objects - private static ArrayList s_ComObjectTypes; // Served COM object types - private static ArrayList s_ClassFactories; // Served COM object class factories - private static string s_appId = "{4e68ec46-5ffc-49e7-b298-38a548df0bfd}"; // Our AppId - private static readonly Object lockObject = new object(); + private static int _objsInUse; // Keeps a count on the total number of objects alive. + private static int _serverLocks; // Keeps a lock count on this application. + private static FrmMain _sMainForm = null; // Reference to our main form + private static ArrayList _sComObjectAssys; // Dynamically loaded assemblies containing served COM objects + private static ArrayList _sComObjectTypes; // Served COM object types + private static ArrayList _sClassFactories; // Served COM object class factories + private static string _sAppId = "{4e68ec46-5ffc-49e7-b298-38a548df0bfd}"; // Our AppId + private static readonly Object LockObject = new object(); #endregion // This property returns the main thread's id. public static uint MainThreadId { get; private set; } // Stores the main thread's thread id. // Used to tell if started by COM or manually - public static bool StartedByCOM { get; private set; } // True if server started by COM (-embedding) + public static bool StartedByCom { get; private set; } // True if server started by COM (-embedding) #region Server Lock, Object Counting, and AutoQuit on COM startup @@ -131,9 +128,9 @@ namespace ASCOM.Meade.net { get { - lock (lockObject) + lock (LockObject) { - return objsInUse; + return _objsInUse; } } } @@ -142,14 +139,14 @@ namespace ASCOM.Meade.net public static int CountObject() { // Increment the global count of objects. - return Interlocked.Increment(ref objsInUse); + return Interlocked.Increment(ref _objsInUse); } // This method performs a thread-safe decrementation the objects count. public static int UncountObject() { // Decrement the global count of objects. - return Interlocked.Decrement(ref objsInUse); + return Interlocked.Decrement(ref _objsInUse); } // Returns the current server lock count. @@ -157,9 +154,9 @@ namespace ASCOM.Meade.net { get { - lock (lockObject) + lock (LockObject) { - return serverLocks; + return _serverLocks; } } } @@ -169,7 +166,7 @@ namespace ASCOM.Meade.net public static int CountLock() { // Increment the global lock count of this server. - return Interlocked.Increment(ref serverLocks); + return Interlocked.Increment(ref _serverLocks); } // This method performs a thread-safe decrementation the @@ -177,7 +174,7 @@ namespace ASCOM.Meade.net public static int UncountLock() { // Decrement the global lock count of this server. - return Interlocked.Decrement(ref serverLocks); + return Interlocked.Decrement(ref _serverLocks); } // AttemptToTerminateServer() will check to see if the objects count and the server @@ -189,11 +186,11 @@ namespace ASCOM.Meade.net // public static void ExitIf() { - lock (lockObject) + lock (LockObject) { if ((ObjectsCount <= 0) && (ServerLockCount <= 0)) { - if (StartedByCOM) + if (StartedByCom) { UIntPtr wParam = new UIntPtr(0); IntPtr lParam = new IntPtr(0); @@ -216,8 +213,8 @@ namespace ASCOM.Meade.net // private static bool LoadComObjectAssemblies() { - s_ComObjectAssys = new ArrayList(); - s_ComObjectTypes = new ArrayList(); + _sComObjectAssys = new ArrayList(); + _sComObjectTypes = new ArrayList(); // put everything into one folder, the same as the server. string assyPath = Assembly.GetEntryAssembly().Location; @@ -246,8 +243,8 @@ namespace ASCOM.Meade.net if (attrbutes.Length > 0) { //MessageBox.Show("Adding Type: " + type.Name + " " + type.FullName); - s_ComObjectTypes.Add(type); //PWGS - much simpler - s_ComObjectAssys.Add(so); + _sComObjectTypes.Add(type); //PWGS - much simpler + _sComObjectAssys.Add(so); } } } @@ -342,10 +339,10 @@ namespace ASCOM.Meade.net // // HKCR\APPID\appid // - using (RegistryKey key = Registry.ClassesRoot.CreateSubKey("APPID\\" + s_appId)) + using (RegistryKey key = Registry.ClassesRoot.CreateSubKey("APPID\\" + _sAppId)) { key.SetValue(null, assyDescription); - key.SetValue("AppID", s_appId); + key.SetValue("AppID", _sAppId); key.SetValue("AuthenticationLevel", 1, RegistryValueKind.DWord); } // @@ -354,7 +351,7 @@ namespace ASCOM.Meade.net using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(string.Format("APPID\\{0}", Application.ExecutablePath.Substring(Application.ExecutablePath.LastIndexOf('\\') + 1)))) { - key.SetValue("AppID", s_appId); + key.SetValue("AppID", _sAppId); } } catch (Exception ex) @@ -370,7 +367,7 @@ namespace ASCOM.Meade.net // // For each of the driver assemblies // - foreach (Type type in s_ComObjectTypes) + foreach (Type type in _sComObjectTypes) { bool bFail = false; try @@ -386,7 +383,7 @@ namespace ASCOM.Meade.net using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(string.Format("CLSID\\{0}", clsid))) { key.SetValue(null, progid); // Could be assyTitle/Desc??, but .NET components show ProgId here - key.SetValue("AppId", s_appId); + key.SetValue("AppId", _sAppId); using (RegistryKey key2 = key.CreateSubKey("Implemented Categories")) { key2.CreateSubKey("{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}"); @@ -420,10 +417,10 @@ namespace ASCOM.Meade.net // Pull the display name from the ServedClassName attribute. attr = Attribute.GetCustomAttribute(type, typeof(ServedClassNameAttribute)); //PWGS Changed to search type for attribute rather than assembly string chooserName = ((ServedClassNameAttribute)attr).DisplayName ?? "MultiServer"; - using (var P = new ASCOM.Utilities.Profile()) + using (var p = new Profile()) { - P.DeviceType = deviceType; - P.Register(progid, chooserName); + p.DeviceType = deviceType; + p.Register(progid, chooserName); } } catch (Exception ex) @@ -456,14 +453,14 @@ namespace ASCOM.Meade.net // // Local server's DCOM/AppID information // - Registry.ClassesRoot.DeleteSubKey(string.Format("APPID\\{0}", s_appId), false); + Registry.ClassesRoot.DeleteSubKey(string.Format("APPID\\{0}", _sAppId), false); Registry.ClassesRoot.DeleteSubKey(string.Format("APPID\\{0}", Application.ExecutablePath.Substring(Application.ExecutablePath.LastIndexOf('\\') + 1)), false); // // For each of the driver assemblies // - foreach (Type type in s_ComObjectTypes) + foreach (Type type in _sComObjectTypes) { string clsid = Marshal.GenerateGuidForType(type).ToString("B"); string progid = Marshal.GenerateProgIdForType(type); @@ -490,10 +487,10 @@ namespace ASCOM.Meade.net // // ASCOM // - using (var P = new ASCOM.Utilities.Profile()) + using (var p = new Profile()) { - P.DeviceType = deviceType; - P.Unregister(progid); + p.DeviceType = deviceType; + p.Unregister(progid); } } catch (Exception) { } @@ -509,11 +506,11 @@ namespace ASCOM.Meade.net // private static bool RegisterClassFactories() { - s_ClassFactories = new ArrayList(); - foreach (Type type in s_ComObjectTypes) + _sClassFactories = new ArrayList(); + foreach (Type type in _sComObjectTypes) { ClassFactory factory = new ClassFactory(type); // Use default context & flags - s_ClassFactories.Add(factory); + _sClassFactories.Add(factory); if (!factory.RegisterClassObject()) { MessageBox.Show("Failed to register class factory for " + type.Name, @@ -528,7 +525,7 @@ namespace ASCOM.Meade.net private static void RevokeClassFactories() { ClassFactory.SuspendClassObjects(); // Prevent race conditions - foreach (ClassFactory factory in s_ClassFactories) + foreach (ClassFactory factory in _sClassFactories) factory.RevokeClassObject(); } #endregion @@ -552,7 +549,7 @@ namespace ASCOM.Meade.net switch (args[0].ToLower()) { case "-embedding": - StartedByCOM = true; // Indicate COM started us + StartedByCom = true; // Indicate COM started us break; case "-register": @@ -578,7 +575,7 @@ namespace ASCOM.Meade.net } } else - StartedByCOM = false; + StartedByCom = false; return bRet; } @@ -598,24 +595,24 @@ namespace ASCOM.Meade.net if (!ProcessArguments(args)) return; // Register/Unregister // Initialize critical member variables. - objsInUse = 0; - serverLocks = 0; + _objsInUse = 0; + _serverLocks = 0; MainThreadId = GetCurrentThreadId(); Thread.CurrentThread.Name = "Main Thread"; Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - s_MainForm = new frmMain(); - if (StartedByCOM) s_MainForm.WindowState = FormWindowState.Minimized; + _sMainForm = new FrmMain(); + if (StartedByCom) _sMainForm.WindowState = FormWindowState.Minimized; // Register the class factories of the served objects RegisterClassFactories(); // Start up the garbage collection thread. - GarbageCollection GarbageCollector = new GarbageCollection(1000); - Thread GCThread = new Thread(new ThreadStart(GarbageCollector.GCWatch)); - GCThread.Name = "Garbage Collection Thread"; - GCThread.Start(); + GarbageCollection garbageCollector = new GarbageCollection(1000); + Thread gcThread = new Thread(new ThreadStart(garbageCollector.GcWatch)); + gcThread.Name = "Garbage Collection Thread"; + gcThread.Start(); // // Start the message loop. This serializes incoming calls to our @@ -623,7 +620,7 @@ namespace ASCOM.Meade.net // try { - Application.Run(s_MainForm); + Application.Run(_sMainForm); } finally { @@ -633,8 +630,8 @@ namespace ASCOM.Meade.net RevokeClassFactories(); // Now stop the Garbage Collector thread. - GarbageCollector.StopThread(); - GarbageCollector.WaitForThreadToStop(); + garbageCollector.StopThread(); + garbageCollector.WaitForThreadToStop(); } } #endregion diff --git a/Meade.net/Localization/LocalisationHelper.cs b/Meade.net/Localization/LocalisationHelper.cs index 9c4b4bf..d193826 100644 --- a/Meade.net/Localization/LocalisationHelper.cs +++ b/Meade.net/Localization/LocalisationHelper.cs @@ -8,7 +8,7 @@ namespace ASCOM.Meade.net.Localization internal class LocalisationHelper { private const string LocalizationNamespace = "LocalisationTest.Localization.Resources.Localization"; - ResourceManager _resourceManager; + private readonly ResourceManager _resourceManager; public LocalisationHelper() { diff --git a/Meade.net/Meade.net.csproj b/Meade.net/Meade.net.csproj index e1d415b..5eda70d 100644 --- a/Meade.net/Meade.net.csproj +++ b/Meade.net/Meade.net.csproj @@ -83,10 +83,39 @@ MinimumRecommendedRules.ruleset - - - - + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Astrometry.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Attributes.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Cache.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Controls.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DeviceInterfaces.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.DriverAccess.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Exceptions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Internal.Extensions.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.SettingsProvider.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.dll + + + ..\packages\ASCOM.Platform.6.4.2\lib\net40\ASCOM.Utilities.Video.dll + @@ -102,7 +131,9 @@ + + Designer frmMain.cs @@ -133,6 +164,8 @@ + + @@ -156,7 +189,6 @@ true - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file