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..a890647 100644 --- a/AstroMath.UnitTests/AstroMathsUnitTests.cs +++ b/AstroMath.UnitTests/AstroMathsUnitTests.cs @@ -1,5 +1,6 @@ using System; using ASCOM.Meade.net; +using ASCOM.Meade.net.AstroMaths; using NUnit.Framework; namespace AstroMath.UnitTests 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/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..b58554d --- /dev/null +++ b/Meade.net.Telescope.UnitTests/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.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("1.0.0.0")] +[assembly: AssemblyFileVersion("1.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..ca26daf --- /dev/null +++ b/Meade.net.Telescope.UnitTests/TelescopeUnitTests.cs @@ -0,0 +1,1531 @@ +using System; +using System.Diagnostics.Eventing.Reader; +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; +using NotImplementedException = ASCOM.NotImplementedException; + +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.AUTOSTAR497_31EE).Returns(() => "31Ee"); + _sharedResourcesWrapperMock.Setup(x => x.AUTOSTAR497_43EG) .Returns(() => "43Eg"); + + _sharedResourcesWrapperMock.Setup(x => x.Lock(It.IsAny())).Callback(action => { action(); }); + + _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); + } + + [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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + _telescope.Connected = true; + _telescope.Action("handbox", action); + + _sharedResourcesWrapperMock.Verify(x => x.SendBlind(expectedString), Times.Once); + } + + [Test] + public void Action_Handbox_nonExistantAction() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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"; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns( () => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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"; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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"; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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.AUTOSTAR497_31EE); + _telescope.Connected = expectedConnected; + + Assert.That(_telescope.Connected, Is.EqualTo(expectedConnected)); + } + + + [Test] + public void Connected_Set_SettingTrueWhenTrue_ThenDoesNothing() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + _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.AUTOSTAR497_31EE); + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + Assert.Throws(() => { var actualResult = _telescope.AlignmentMode; }); + } + + [Test] + public void AlignmentMode_Set_WhenNotConnected_ThrowsException() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_43EG); + _telescope.Connected = true; + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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; + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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; + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _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($":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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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"; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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"; + + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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() + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + 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) + { + _sharedResourcesWrapperMock.Setup(x => x.ProductName).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497); + _sharedResourcesWrapperMock.Setup(x => x.FirmwareVersion).Returns(() => _sharedResourcesWrapperMock.Object.AUTOSTAR497_31EE); + _telescope.Connected = true; + + _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)); + } + } +} 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..a00f7db --- /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 89% rename from Meade.net.Telescope/AstroMaths.cs rename to Meade.net.Telescope/AstroMaths/AstroMaths.cs index 7123eaa..45fea5f 100644 --- a/Meade.net.Telescope/AstroMaths.cs +++ b/Meade.net.Telescope/AstroMaths/AstroMaths.cs @@ -1,30 +1,9 @@ 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. 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..ff4ef4e --- /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/Telescope.cs b/Meade.net.Telescope/Telescope.cs index 5d59eb1..6b7e8ce 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.Reflection; +using ASCOM.Meade.net.AstroMaths; +using ASCOM.Meade.net.Wrapper; +using ASCOM.Utilities.Interfaces; namespace ASCOM.Meade.net { @@ -76,34 +47,27 @@ namespace ASCOM.Meade.net /// private static 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 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() { + //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 ASCOM.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 ASCOM.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 @@ -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; } public bool Connected @@ -308,7 +293,7 @@ namespace ASCOM.Meade.net } set { - tl.LogMessage("Connected", "Set {0}", value); + LogMessage("Connected", "Set {0}", value); if (value == IsConnected) return; @@ -317,23 +302,22 @@ namespace ASCOM.Meade.net 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 = INVALID_PARAMETER; + _targetRightAscension = INVALID_PARAMETER; - _connectedState = true; + LogMessage("Connected Set", $"New Pulse Guiding Supported: {_userNewerPulseGuiding}"); + IsConnected = true; } catch (Exception) { - SharedResources.Disconnect("Serial"); + _sharedResourcesWrapper.Disconnect("Serial"); throw; } } @@ -345,17 +329,17 @@ namespace ASCOM.Meade.net else { LogMessage("Connected Set", "Disconnecting from port {0}", comPort); - SharedResources.Disconnect("Serial"); - _connectedState = false; + _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.AUTOSTAR497_31EE); } return false; @@ -363,26 +347,26 @@ namespace ASCOM.Meade.net private bool FirmwareIsGreaterThan(string minVersion) { - var currentVersion = SharedResources.FirmwareVersion; + var currentVersion = _sharedResourcesWrapper.FirmwareVersion; var comparison = currentVersion.CompareTo(minVersion); 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 +375,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,7 +394,7 @@ namespace ASCOM.Meade.net // TODO customise this device description get { - tl.LogMessage("Description Get", driverDescription); + LogMessage("Description Get", driverDescription); return driverDescription; } } @@ -413,11 +403,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; } } @@ -427,9 +415,8 @@ 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); + string driverVersion = $"{version.Major}.{version.Minor}.{version.Revision}.{version.Build}"; + LogMessage("DriverVersion Get", driverVersion); return driverVersion; } } @@ -450,17 +437,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); + LogMessage("Name Get", name); return name; } } @@ -473,8 +460,8 @@ 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 } @@ -483,13 +470,13 @@ namespace ASCOM.Meade.net { 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 +484,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 +513,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.AUTOSTAR497_43EG)) + 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; @@ -559,27 +555,27 @@ namespace ASCOM.Meade.net 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, @@ -601,7 +597,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("ApertureArea Get", "Not implemented"); + LogMessage("ApertureArea Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("ApertureArea", false); } } @@ -610,7 +606,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("ApertureDiameter Get", "Not implemented"); + LogMessage("ApertureDiameter Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("ApertureDiameter", false); } } @@ -619,7 +615,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("AtHome", "Get - " + false.ToString()); + LogMessage("AtHome", "Get - " + false.ToString()); return false; } } @@ -630,7 +626,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("AtPark", "Get - " + _atPark); + LogMessage("AtPark", "Get - " + _atPark); return _atPark; } private set { _atPark = value; } @@ -638,7 +634,7 @@ namespace ASCOM.Meade.net public IAxisRates AxisRates(TelescopeAxes Axis) { - tl.LogMessage("AxisRates", "Get - " + Axis.ToString()); + LogMessage("AxisRates", "Get - " + Axis.ToString()); return new AxisRates(Axis); } @@ -648,18 +644,18 @@ namespace ASCOM.Meade.net { 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,14 +664,14 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanFindHome", "Get - " + false.ToString()); + LogMessage("CanFindHome", "Get - " + false.ToString()); return false; } } public bool CanMoveAxis(TelescopeAxes Axis) { - tl.LogMessage("CanMoveAxis", "Get - " + Axis.ToString()); + LogMessage("CanMoveAxis", "Get - " + Axis.ToString()); switch (Axis) { case TelescopeAxes.axisPrimary: return true; //RA or AZ @@ -689,7 +685,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanPark", "Get - " + true.ToString()); + LogMessage("CanPark", "Get - " + true.ToString()); return true; } } @@ -698,7 +694,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanPulseGuide", "Get - " + true.ToString()); + LogMessage("CanPulseGuide", "Get - " + true.ToString()); return true; } } @@ -707,7 +703,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetDeclinationRate", "Get - " + false.ToString()); + LogMessage("CanSetDeclinationRate", "Get - " + false.ToString()); return false; } } @@ -716,7 +712,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetGuideRates", "Get - " + false.ToString()); + LogMessage("CanSetGuideRates", "Get - " + false.ToString()); return false; } } @@ -725,7 +721,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetPark", "Get - " + false.ToString()); + LogMessage("CanSetPark", "Get - " + false.ToString()); return false; } } @@ -734,7 +730,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetPierSide", "Get - " + false.ToString()); + LogMessage("CanSetPierSide", "Get - " + false.ToString()); return false; } } @@ -743,7 +739,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetRightAscensionRate", "Get - " + false.ToString()); + LogMessage("CanSetRightAscensionRate", "Get - " + false.ToString()); return false; } } @@ -752,7 +748,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSetTracking", "Get - " + true.ToString()); + LogMessage("CanSetTracking", "Get - " + true.ToString()); return true; } } @@ -761,7 +757,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSlew", "Get - " + true.ToString()); + LogMessage("CanSlew", "Get - " + true.ToString()); return true; } } @@ -770,7 +766,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSlewAltAz", "Get - " + true.ToString()); + LogMessage("CanSlewAltAz", "Get - " + true.ToString()); return true; } } @@ -779,7 +775,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSlewAltAzAsync", "Get - " + true.ToString()); + LogMessage("CanSlewAltAzAsync", "Get - " + true.ToString()); return true; } } @@ -788,7 +784,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSlewAsync", "Get - " + true.ToString()); + LogMessage("CanSlewAsync", "Get - " + true.ToString()); return true; } } @@ -797,7 +793,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSync", "Get - " + true.ToString()); + LogMessage("CanSync", "Get - " + true.ToString()); return true; } } @@ -806,7 +802,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanSyncAltAz", "Get - " + false.ToString()); + LogMessage("CanSyncAltAz", "Get - " + false.ToString()); return false; } } @@ -815,7 +811,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("CanUnpark", "Get - " + false.ToString()); + LogMessage("CanUnpark", "Get - " + false.ToString()); return false; } } @@ -826,14 +822,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,32 +839,32 @@ namespace ASCOM.Meade.net get { double declination = 0.0; - tl.LogMessage("DeclinationRate", "Get - " + declination.ToString()); + LogMessage("DeclinationRate", "Get - " + declination.ToString()); return declination; } set { - tl.LogMessage("DeclinationRate Set", "Not implemented"); + LogMessage("DeclinationRate Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("DeclinationRate", true); } } public PierSide DestinationSideOfPier(double rightAscension, double declination) { - tl.LogMessage("DestinationSideOfPier Get", "Not implemented"); - throw new ASCOM.PropertyNotImplementedException("DestinationSideOfPier", false); + LogMessage("DestinationSideOfPier Get", "Not implemented"); + throw new ASCOM.MethodNotImplementedException("DestinationSideOfPier"); } public bool DoesRefraction { get { - tl.LogMessage("DoesRefraction Get", "Not implemented"); + LogMessage("DoesRefraction Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("DoesRefraction", false); } set { - tl.LogMessage("DoesRefraction Set", "Not implemented"); + LogMessage("DoesRefraction Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("DoesRefraction", true); } } @@ -878,14 +874,14 @@ 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"); + LogMessage("FindHome", "Not implemented"); throw new ASCOM.MethodNotImplementedException("FindHome"); } @@ -893,7 +889,7 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("FocalLength Get", "Not implemented"); + LogMessage("FocalLength Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("FocalLength", false); } } @@ -902,12 +898,12 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("GuideRateDeclination Get", "Not implemented"); + LogMessage("GuideRateDeclination Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("GuideRateDeclination", false); } set { - tl.LogMessage("GuideRateDeclination Set", "Not implemented"); + LogMessage("GuideRateDeclination Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("GuideRateDeclination", true); } } @@ -916,12 +912,12 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("GuideRateRightAscension Get", "Not implemented"); + LogMessage("GuideRateRightAscension Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("GuideRateRightAscension", false); } set { - tl.LogMessage("GuideRateRightAscension Set", "Not implemented"); + LogMessage("GuideRateRightAscension Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("GuideRateRightAscension", true); } } @@ -930,7 +926,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 +938,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,22 +949,22 @@ 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; @@ -981,23 +978,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 +1005,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 +1029,19 @@ namespace ASCOM.Meade.net break; default: - throw new ASCOM.MethodNotImplementedException("Can not move this axis."); + throw new ASCOM.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 +1051,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 +1073,7 @@ namespace ASCOM.Meade.net if (_userNewerPulseGuiding) { - SharedResources.SendBlind($":Mg{d}{duration:0000}#"); + _sharedResourcesWrapper.SendBlind($":Mg{d}{duration:0000}#"); //:MgnDDDD# //:MgsDDDD# //:MgeDDDD# @@ -1086,16 +1083,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 +1102,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 +1121,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,19 +1138,19 @@ namespace ASCOM.Meade.net get { double rightAscensionRate = 0.0; - tl.LogMessage("RightAscensionRate", "Get - " + rightAscensionRate.ToString()); + LogMessage("RightAscensionRate", "Get - " + rightAscensionRate.ToString()); return rightAscensionRate; } set { - tl.LogMessage("RightAscensionRate Set", "Not implemented"); + LogMessage("RightAscensionRate Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("RightAscensionRate", true); } } public void SetPark() { - tl.LogMessage("SetPark", "Not implemented"); + LogMessage("SetPark", "Not implemented"); throw new ASCOM.MethodNotImplementedException("SetPark"); } @@ -1160,12 +1158,12 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("SideOfPier Get", "Not implemented"); + LogMessage("SideOfPier Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SideOfPier", false); } set { - tl.LogMessage("SideOfPier Set", "Not implemented"); + LogMessage("SideOfPier Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SideOfPier", true); } } @@ -1178,7 +1176,7 @@ namespace ASCOM.Meade.net double siderealTime = 0.0; using (var novas = new ASCOM.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, @@ -1189,9 +1187,9 @@ namespace ASCOM.Meade.net 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()); return siderealTime; } } @@ -1200,12 +1198,12 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("SiteElevation Get", "Not implemented"); + LogMessage("SiteElevation Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SiteElevation", false); } set { - tl.LogMessage("SiteElevation Set", "Not implemented"); + LogMessage("SiteElevation Set", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SiteElevation", true); } } @@ -1216,18 +1214,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 +1236,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 +1259,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# //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 +1295,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 +1312,26 @@ namespace ASCOM.Meade.net { get { - tl.LogMessage("SlewSettleTime Get", "Not implemented"); + LogMessage("SlewSettleTime Get", "Not implemented"); throw new ASCOM.PropertyNotImplementedException("SlewSettleTime", false); } set { - tl.LogMessage("SlewSettleTime Set", "Not implemented"); + LogMessage("SlewSettleTime Set", "Not implemented"); throw new ASCOM.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(); } } @@ -1346,10 +1349,10 @@ namespace ASCOM.Meade.net //todo this serial string does not work. Calculate the EQ version instead. - var dms = utilities.DegreesToDMS(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: @@ -1375,9 +1378,9 @@ namespace ASCOM.Meade.net //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: @@ -1404,7 +1407,7 @@ namespace ASCOM.Meade.net if (azimuth < 0) throw new ASCOM.InvalidValueException("Azimuth cannot be less than 0."); - tl.LogMessage("SlewToAltAzAsync", $"Az={azimuth} Alt={altitude}"); + LogMessage("SlewToAltAzAsync", $"Az={azimuth} Alt={altitude}"); CheckConnected("SlewToAltAzAsync"); HorizonCoordinates altAz = new HorizonCoordinates(); @@ -1415,7 +1418,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 +1438,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 +1454,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}\""); + string belowHorizonMessage = _sharedResourcesWrapper.ReadTerminated(); + LogMessage("DoSlewAsync", $"Slew failed \"{belowHorizonMessage}\""); throw new ASCOM.InvalidOperationException(belowHorizonMessage); case "2": //Below Horizon - string belowMinimumElevationMessage = SharedResources.ReadTerminated(); - tl.LogMessage("DoSlewAsync", $"Slew failed \"{belowMinimumElevationMessage}\""); + string belowMinimumElevationMessage = _sharedResourcesWrapper.ReadTerminated(); + LogMessage("DoSlewAsync", $"Slew failed \"{belowMinimumElevationMessage}\""); throw new ASCOM.InvalidOperationException(belowMinimumElevationMessage); default: - tl.LogMessage("DoSlewAsync", $"Slew failed - unknown response \"{response}\""); + LogMessage("DoSlewAsync", $"Slew failed - unknown response \"{response}\""); throw new ASCOM.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 @@ -1490,25 +1493,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,13 +1523,13 @@ 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); } } @@ -1559,30 +1562,30 @@ namespace ASCOM.Meade.net 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. 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"); + LogMessage("SyncToAltAz", "Not implemented"); throw new ASCOM.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,14 +1596,14 @@ 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"); @@ -1623,29 +1626,29 @@ namespace ASCOM.Meade.net //return targetDec; - tl.LogMessage("TargetDeclination Get", $"{_targetDeclination}"); + LogMessage("TargetDeclination Get", $"{_targetDeclination}"); return _targetDeclination; } set { - tl.LogMessage("TargetDeclination Set", $"{value}"); - + LogMessage("TargetDeclination Set", $"{value}"); + + CheckConnected("TargetDeclination Set"); + //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."); - - CheckConnected("TargetDeclination Set"); - - var dms = utilities.DegreesToDMS(value, "*", ":", ":", 2); + + 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: @@ -1677,12 +1680,12 @@ 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}"); if (value < 0) throw new InvalidValueException("Right ascension value cannot be below 0"); @@ -1693,8 +1696,8 @@ namespace ASCOM.Meade.net 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 +1717,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 +1745,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 +1787,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; } @@ -1797,7 +1800,7 @@ namespace ASCOM.Meade.net { 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 @@ -1820,16 +1823,16 @@ 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# //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# //The Local Time in 24 - hour Format @@ -1854,22 +1857,22 @@ namespace ASCOM.Meade.net var utcDate = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Utc) + 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}#"); + var timeResult = _sharedResourcesWrapper.SendChar($":SL{localDateTime:HH:mm:ss}#"); //:SLHH:MM:SS# //Set the local Time //Returns: @@ -1880,7 +1883,7 @@ namespace ASCOM.Meade.net throw new InvalidOperationException("Failed to set local time"); } - var dateResult = SharedResources.SendChar($":SC{localDateTime:MM/dd/yy}#"); + var dateResult = _sharedResourcesWrapper.SendChar($":SC{localDateTime:MM/dd/yy}#"); //:SCMM/DD/YY# //Change Handbox Date to MM/DD/YY //Returns: @@ -1893,15 +1896,15 @@ 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"); + LogMessage("Unpark", "Not implemented"); throw new ASCOM.MethodNotImplementedException("Unpark"); } @@ -1988,14 +1991,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 +2001,7 @@ namespace ASCOM.Meade.net { if (!IsConnected) { - throw new ASCOM.NotConnectedException(message); + throw new ASCOM.NotConnectedException($"Not connected to telescope when trying to execute: {message}"); } } @@ -2014,7 +2010,7 @@ namespace ASCOM.Meade.net /// internal void ReadProfile() { - var profileProperties = SharedResources.ReadProfile(); + var profileProperties = _sharedResourcesWrapper.ReadProfile(); tl.Enabled = profileProperties.TraceLogger; comPort = profileProperties.ComPort; } @@ -2025,7 +2021,7 @@ 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); 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..62d4ba3 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 @@ -76,47 +45,41 @@ namespace ASCOM.Meade.net /// private static 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 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; + private readonly ISharedResourcesWrapper _sharedResourcesWrapper; + /// /// Initializes a new instance of the class. /// Must be public for COM registration. /// public Focuser() + { + //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"); - ReadProfile(); // Read device configuration from the ASCOM Profile store tl.LogMessage("Focuser", "Starting initialisation"); + ReadProfile(); // Read device configuration from the ASCOM Profile store - connectedState = false; // Initialise connected to false - utilities = new Util(); //Initialise util object - astroUtilities = new AstroUtils(); // Initialise astro utilities object + IsConnected = false; // Initialise connected to false tl.LogMessage("Focuser", "Completed initialisation"); } @@ -137,7 +100,7 @@ namespace ASCOM.Meade.net public void SetupDialog() { tl.LogMessage("SetupDialog", "Opening setup dialog"); - SharedResources.SetupDialog(); + _sharedResourcesWrapper.SetupDialog(); ReadProfile(); tl.LogMessage("SetupDialog", "complete"); } @@ -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 @@ -184,7 +147,7 @@ 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"); } @@ -195,10 +158,6 @@ namespace ASCOM.Meade.net tl.Enabled = false; tl.Dispose(); tl = null; - utilities.Dispose(); - utilities = null; - astroUtilities.Dispose(); - astroUtilities = null; } public bool Connected @@ -218,17 +177,17 @@ 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; } } @@ -240,17 +199,17 @@ namespace ASCOM.Meade.net else { LogMessage("Connected Set", "Disconnecting from port {0}", comPort); - SharedResources.Disconnect("Serial"); - connectedState = false; + _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 @@ -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); } } @@ -436,9 +395,9 @@ namespace ASCOM.Meade.net 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,26 +407,26 @@ 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); }); } @@ -604,14 +563,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 @@ -630,7 +582,7 @@ namespace ASCOM.Meade.net /// internal void ReadProfile() { - var profileProperties = SharedResources.ReadProfile(); + var profileProperties = _sharedResourcesWrapper.ReadProfile(); tl.Enabled = profileProperties.TraceLogger; comPort = profileProperties.ComPort; } 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/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/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