Merge branch 'develop' into feature/GWSupport

This commit is contained in:
Sebastian Godelet
2021-06-25 14:49:25 +10:00
19 changed files with 1817 additions and 814 deletions
+2 -1
View File
@@ -123,7 +123,8 @@ namespace AstroMath.UnitTests
var altAz = _astroMath.ConvertEqToHoz(hourAngle, latitude, equatorialCoordinates); var altAz = _astroMath.ConvertEqToHoz(hourAngle, latitude, equatorialCoordinates);
Assert.That(altAz.Altitude, Is.EqualTo(20.958562421092779)); Assert.That(altAz.Altitude, Is.GreaterThan(20.958562421092770));
Assert.That(altAz.Altitude, Is.LessThanOrEqualTo(20.958562421092779));
Assert.That(altAz.Azimuth, Is.EqualTo(281.2728706962269)); Assert.That(altAz.Azimuth, Is.EqualTo(281.2728706962269));
} }
+21 -17
View File
@@ -109,16 +109,17 @@ namespace Meade.net.Focuser.UnitTests
Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: CommandBlind")); Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: CommandBlind"));
} }
[Test] [TestCase(false)]
public void CommandBlind_WhenConnected_ThenSendsExpectedMessage() [TestCase(true)]
public void CommandBlind_WhenConnected_ThenSendsExpectedMessage(bool raw)
{ {
string expectedMessage = "test blind Message"; string expectedMessage = "test blind Message";
ConnectFocuser(); ConnectFocuser();
_focuser.CommandBlind(expectedMessage, true); _focuser.CommandBlind(expectedMessage, raw);
_sharedResourcesWrapperMock.Verify(x => x.SendBlind(expectedMessage), Times.Once); _sharedResourcesWrapperMock.Verify(x => x.SendBlind(expectedMessage, raw), Times.Once);
} }
[Test] [Test]
@@ -130,16 +131,19 @@ namespace Meade.net.Focuser.UnitTests
Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: CommandBool")); Assert.That(exception.Message, Is.EqualTo("Not connected to focuser when trying to execute: CommandBool"));
} }
[Test] [TestCase(false)]
public void CommandBool_WhenConnected_ThenSendsExpectedMessage() [TestCase(true)]
public void CommandBool_WhenConnected_ThenSendsExpectedMessage(bool raw)
{ {
string expectedMessage = "test blind Message"; string expectedMessage = "test blind Message";
_sharedResourcesWrapperMock.Setup(x => x.SendBool(expectedMessage, raw)).Returns(true);
ConnectFocuser(); ConnectFocuser();
var exception = Assert.Throws<MethodNotImplementedException>(() => { _focuser.CommandBool(expectedMessage, true); }); var result = _focuser.CommandBool(expectedMessage, raw);
Assert.That(exception.Message, Is.EqualTo("Method CommandBool is not implemented in this driver.")); _sharedResourcesWrapperMock.Verify(x => x.SendBool(expectedMessage, raw), Times.Once);
Assert.That(result, Is.True);
} }
[Test] [Test]
@@ -319,7 +323,7 @@ namespace Meade.net.Focuser.UnitTests
_focuser.Halt(); _focuser.Halt();
_sharedResourcesWrapperMock.Verify( x => x.SendBlind(":FQ#"), Times.AtLeastOnce); _sharedResourcesWrapperMock.Verify(x => x.SendBlind("FQ", false), Times.AtLeastOnce);
} }
[Test] [Test]
@@ -409,13 +413,13 @@ namespace Meade.net.Focuser.UnitTests
if (position < 0) if (position < 0)
{ {
_sharedResourcesWrapperMock.Verify( x => x.SendBlind(":F-#"), Times.Once); _sharedResourcesWrapperMock.Verify(x => x.SendBlind("F-", false), Times.Once);
_sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F+#"), Times.Never); _sharedResourcesWrapperMock.Verify(x => x.SendBlind("F+", false), Times.Never);
} }
else else
{ {
_sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F-#"), Times.Never); _sharedResourcesWrapperMock.Verify(x => x.SendBlind("F-", false), Times.Never);
_sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F+#"), Times.Once); _sharedResourcesWrapperMock.Verify(x => x.SendBlind("F+", false), Times.Once);
} }
_sharedResourcesWrapperMock.Verify(x => x.Lock(It.IsAny<Action>()), Times.Once); _sharedResourcesWrapperMock.Verify(x => x.Lock(It.IsAny<Action>()), Times.Once);
@@ -437,16 +441,16 @@ namespace Meade.net.Focuser.UnitTests
if (position < 0) if (position < 0)
{ {
_sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F-#"), Times.Once); _sharedResourcesWrapperMock.Verify(x => x.SendBlind("F-", false), Times.Once);
_sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F+#"), Times.Never); _sharedResourcesWrapperMock.Verify(x => x.SendBlind("F+", false), Times.Never);
_utilMock.Verify(x => x.WaitForMilliseconds(Math.Abs(position)), Times.Once); _utilMock.Verify(x => x.WaitForMilliseconds(Math.Abs(position)), Times.Once);
_utilMock.Verify(x => x.WaitForMilliseconds(Math.Abs(_profileProperties.BacklashCompensation)), Times.Never); _utilMock.Verify(x => x.WaitForMilliseconds(Math.Abs(_profileProperties.BacklashCompensation)), Times.Never);
_utilMock.Verify(x => x.WaitForMilliseconds(100), Times.Exactly(1)); _utilMock.Verify(x => x.WaitForMilliseconds(100), Times.Exactly(1));
} }
else else
{ {
_sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F-#"), Times.Once); _sharedResourcesWrapperMock.Verify(x => x.SendBlind("F-", false), Times.Once);
_sharedResourcesWrapperMock.Verify(x => x.SendBlind(":F+#"), Times.Once); _sharedResourcesWrapperMock.Verify(x => x.SendBlind("F+", false), Times.Once);
_utilMock.Verify(x => x.WaitForMilliseconds(Math.Abs(position) + _profileProperties.BacklashCompensation), Times.Once); _utilMock.Verify(x => x.WaitForMilliseconds(Math.Abs(position) + _profileProperties.BacklashCompensation), Times.Once);
_utilMock.Verify(x => x.WaitForMilliseconds(_profileProperties.BacklashCompensation), Times.Once); _utilMock.Verify(x => x.WaitForMilliseconds(_profileProperties.BacklashCompensation), Times.Once);
_utilMock.Verify(x => x.WaitForMilliseconds(100), Times.Exactly(2)); _utilMock.Verify(x => x.WaitForMilliseconds(100), Times.Exactly(2));
File diff suppressed because it is too large Load Diff
@@ -62,7 +62,7 @@
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>..\bin\Release\</OutputPath> <OutputPath>..\bin\Release\</OutputPath>
<Prefer32Bit>false</Prefer32Bit> <Prefer32Bit>true</Prefer32Bit>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<OutputPath>..\bin\Debug\</OutputPath> <OutputPath>..\bin\Debug\</OutputPath>
File diff suppressed because it is too large Load Diff
@@ -98,6 +98,10 @@
<ItemGroup> <ItemGroup>
<Compile Include="SharedResourcesUnitTests.cs" /> <Compile Include="SharedResourcesUnitTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ThreadSafeBoolTests.cs" />
<Compile Include="ThreadSafeDateTimeTests.cs" />
<Compile Include="ThreadSafeEnumTests.cs" />
<Compile Include="ThreadSafeNullableDoubleTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Meade.net\Meade.net.csproj"> <ProjectReference Include="..\Meade.net\Meade.net.csproj">
+44 -12
View File
@@ -1,6 +1,7 @@
using System; using System;
using System.Globalization; using System.Globalization;
using ASCOM.DeviceInterface;
using ASCOM.Meade.net; using ASCOM.Meade.net;
using ASCOM.Meade.net.Wrapper; using ASCOM.Meade.net.Wrapper;
using ASCOM.Utilities.Interfaces; using ASCOM.Utilities.Interfaces;
@@ -32,35 +33,36 @@ namespace Meade.net.UnitTests
Assert.That(SharedResources.SharedSerial, Is.EqualTo(_serialMock.Object)); Assert.That(SharedResources.SharedSerial, Is.EqualTo(_serialMock.Object));
} }
[Test] [TestCase(true, "Test")]
public void SendBlind_WhenCalled_Then_ClearsBuffersAndSendsMessage() [TestCase(false, "#:Test#")]
public void SendBlind_WhenCalled_Then_ClearsBuffersAndSendsMessage(bool raw, string expectedMessage)
{ {
var expectedMessage = "Test"; var sendMessage = "Test";
SharedResources.SendBlind(sendMessage, raw);
SharedResources.SendBlind(expectedMessage);
_serialMock.Verify(x=> x.ClearBuffers(), Times.Once); _serialMock.Verify(x=> x.ClearBuffers(), Times.Once);
_serialMock.Verify(x=>x.Transmit(expectedMessage), Times.Once); _serialMock.Verify(x=>x.Transmit(expectedMessage), Times.Once);
} }
[Test] [TestCase(false, "#:Test#")]
public void SendChar_WhenCalled_ThenSendsMessageAndReadsExpectedNumberOfCharacters() [TestCase(true, "Test")]
public void SendChar_WhenCalled_ThenSendsMessageAndReadsExpectedNumberOfCharacters(bool raw, string expectedCommand)
{ {
var expectedMessage = "Test"; var command = "Test";
var expectedResult = "A"; var expectedResult = "A";
_serialMock.Setup(x => x.ReceiveCounted(1)).Returns(expectedResult); _serialMock.Setup(x => x.ReceiveCounted(1)).Returns(expectedResult);
var result = SharedResources.SendChar(expectedMessage); var result = SharedResources.SendChar(command, raw);
_serialMock.Verify(x => x.ClearBuffers(), Times.Once); _serialMock.Verify(x => x.ClearBuffers(), Times.Once);
_serialMock.Verify(x => x.Transmit(expectedMessage), Times.Once); _serialMock.Verify(x => x.Transmit(expectedCommand), Times.Once);
_serialMock.Verify(x => x.ReceiveCounted(1), Times.Once); _serialMock.Verify(x => x.ReceiveCounted(1), Times.Once);
Assert.That(result, Is.EqualTo(expectedResult)); Assert.That(result, Is.EqualTo(expectedResult));
} }
[TestCase(false, "Test")] [TestCase(true, "Test")]
[TestCase(true, "#Test")] [TestCase(false, "#:Test#")]
public void SendString_WhenCalled_ThenSendsMessageAndReadsResultUntilTerminatorFound(bool includePrefix, string expectedMessage) public void SendString_WhenCalled_ThenSendsMessageAndReadsResultUntilTerminatorFound(bool includePrefix, string expectedMessage)
{ {
var transmitMessage = "Test"; var transmitMessage = "Test";
@@ -617,5 +619,35 @@ namespace Meade.net.UnitTests
_traceLoggerMock.Verify( x => x.LogIssue("Connect", "Unable to decode response from the telescope, This is likely a hardware serial communications error."), Times.Once); _traceLoggerMock.Verify( x => x.LogIssue("Connect", "Unable to decode response from the telescope, This is likely a hardware serial communications error."), Times.Once);
} }
[Test]
public void CheckIsParkedIsFalseByDefault() => Assert.That(SharedResources.IsParked, Is.False);
[Test]
public void CheckParkedPositionIsNullByDefault() => Assert.That(SharedResources.ParkedPosition, Is.Null);
[Test]
public void CheckIsLongFormatIsFalseByDefault() => Assert.That(SharedResources.IsLongFormat, Is.False);
[Test]
public void CheckMovingPrimaryIsFalseBydefault() => Assert.That(SharedResources.MovingPrimary, Is.False);
[Test]
public void CheckMovingSecondaryIsFalseBydefault() => Assert.That(SharedResources.MovingSecondary, Is.False);
[Test]
public void CheckSideOfPierIsUnknownByDefault() => Assert.That(SharedResources.SideOfPier, Is.EqualTo(PierSide.pierUnknown));
[Test]
public void CheckSlewSettleTimeIsZeroByDefault() => Assert.That(SharedResources.SlewSettleTime, Is.EqualTo((short)0));
[Test]
public void CheckEarliestNonNonSlewingTimeIsMinValueByDefault() => Assert.That(SharedResources.EarliestNonSlewingTime, Is.EqualTo(DateTime.MinValue));
[Test]
public void CheckTargetDeclinationIsNullByDefault() => Assert.That(SharedResources.TargetDeclination.HasValue, Is.False);
[Test]
public void CheckTargetRightAscensionIsNullByDefault() => Assert.That(SharedResources.TargetRightAscension.HasValue, Is.False);
} }
} }
@@ -0,0 +1,39 @@
using ASCOM.Meade.net;
using NUnit.Framework;
namespace Meade.net.UnitTests
{
public class ThreadSafeBoolTests
{
[TestCase(false)]
[TestCase(true)]
public void When_Assigned_ThenValueIsSame(bool value)
{
// given
ThreadSafeValue<bool> sut = value;
// when
bool actual = sut;
// then
Assert.That(actual, Is.EqualTo(value));
}
[TestCase(false, false)]
[TestCase(false, true)]
[TestCase(true, false)]
[TestCase(true, true)]
public void When_SetValue_ThenValueIsUpdated(bool initialValue, bool setValue)
{
// given
ThreadSafeValue<bool> sut = initialValue;
// when
sut.Set(setValue);
bool afterset = sut;
// then
Assert.That(afterset, Is.EqualTo(setValue));
}
}
}
@@ -0,0 +1,61 @@
using ASCOM.Meade.net;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Globalization;
namespace Meade.net.UnitTests
{
public class ThreadSafeDateTimeTests
{
[TestCaseSource(nameof(DateTimeSource))]
public void When_Assigned_ThenValueIsSame(DateTime value)
{
// given
ThreadSafeValue<DateTime> sut = value;
// when
DateTime actual = sut;
// then
Assert.That(actual, Is.EqualTo(value));
}
[TestCaseSource(nameof(DateTimeSetSource))]
public void When_SetValue_ThenValueIsUpdated(DateTime initialValue, DateTime setValue)
{
// given
ThreadSafeValue<DateTime> sut = initialValue;
// when
sut.Set(setValue);
DateTime afterset = sut;
// then
Assert.That(afterset, Is.EqualTo(setValue));
}
static readonly DateTime Example1 = DateTimeOffset.Parse("2012-05-09T02:10:31.296761Z", CultureInfo.InvariantCulture).UtcDateTime;
static readonly DateTime Example2 = DateTimeOffset.Parse("2051-03-09T23:15:11.556081Z", CultureInfo.InvariantCulture).UtcDateTime;
static IEnumerable<DateTime> DateTimeSource => new[]
{
DateTime.MinValue,
Example1,
Example2
};
static IEnumerable<TestCaseData> DateTimeSetSource => new[]
{
new TestCaseData(DateTime.MinValue, Example1),
new TestCaseData(DateTime.MinValue, Example2),
new TestCaseData(DateTime.MinValue, DateTime.MinValue),
new TestCaseData(Example1, Example1),
new TestCaseData(Example1, Example2),
new TestCaseData(Example1, DateTime.MinValue),
new TestCaseData(Example2, Example1),
new TestCaseData(Example2, Example2),
new TestCaseData(Example2, DateTime.MinValue)
};
}
}
@@ -0,0 +1,46 @@
using ASCOM.DeviceInterface;
using ASCOM.Meade.net;
using NUnit.Framework;
namespace Meade.net.UnitTests
{
public class ThreadSafeEnumTests
{
[TestCase(PierSide.pierUnknown)]
[TestCase(PierSide.pierEast)]
[TestCase(PierSide.pierWest)]
public void When_Assigned_ThenValueIsSame(PierSide value)
{
// given
ThreadSafeValue<PierSide> sut = value;
// when
PierSide actual = sut;
// then
Assert.That(actual, Is.EqualTo(value));
}
[TestCase(PierSide.pierUnknown, PierSide.pierUnknown)]
[TestCase(PierSide.pierUnknown, PierSide.pierEast)]
[TestCase(PierSide.pierUnknown, PierSide.pierWest)]
[TestCase(PierSide.pierEast, PierSide.pierUnknown)]
[TestCase(PierSide.pierEast, PierSide.pierEast)]
[TestCase(PierSide.pierEast, PierSide.pierWest)]
[TestCase(PierSide.pierWest, PierSide.pierUnknown)]
[TestCase(PierSide.pierWest, PierSide.pierEast)]
[TestCase(PierSide.pierWest, PierSide.pierWest)]
public void When_SetValue_ThenValueIsUpdated(PierSide initialValue, PierSide setValue)
{
// given
ThreadSafeValue<PierSide> sut = initialValue;
// when
sut.Set(setValue);
PierSide afterset = sut;
// then
Assert.That(afterset, Is.EqualTo(setValue));
}
}
}
@@ -0,0 +1,45 @@
using ASCOM.Meade.net;
using NUnit.Framework;
namespace Meade.net.UnitTests
{
public class ThreadSafeNullableDoubleTests
{
[TestCase(0.1d)]
[TestCase(-12.34d)]
[TestCase(0d)]
[TestCase(null)]
public void When_Assigned_ThenValueIsSame(double? value)
{
// given
ThreadSafeValue<double?> sut = value;
// when
double? actual = sut;
// then
Assert.That(actual, Is.EqualTo(value));
}
[TestCase(0.1d, 0.2d)]
[TestCase(-12.34d, 5d)]
[TestCase(0d, 1d)]
[TestCase(null, 2d)]
[TestCase(0.1d, null)]
[TestCase(-12.34d, null)]
[TestCase(0d, null)]
[TestCase(null, null)]
public void When_SetValue_ThenValueIsUpdated(double? initialValue, double? setValue)
{
// given
ThreadSafeValue<double?> sut = initialValue;
// when
sut.Set(setValue);
double? afterset = sut;
// then
Assert.That(afterset, Is.EqualTo(setValue));
}
}
}
+1
View File
@@ -5,6 +5,7 @@
<package id="JetBrains.Annotations" version="2020.3.0" targetFramework="net472" /> <package id="JetBrains.Annotations" version="2020.3.0" targetFramework="net472" />
<package id="Moq" version="4.15.2" targetFramework="net472" /> <package id="Moq" version="4.15.2" targetFramework="net472" />
<package id="NUnit" version="3.13.0" targetFramework="net472" /> <package id="NUnit" version="3.13.0" targetFramework="net472" />
<package id="NUnit.ConsoleRunner" version="3.12.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" targetFramework="net472" /> <package id="System.Runtime.CompilerServices.Unsafe" version="5.0.0" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" /> <package id="System.Threading.Tasks.Extensions" version="4.5.4" targetFramework="net472" />
</packages> </packages>
+17 -10
View File
@@ -101,32 +101,39 @@ namespace ASCOM.Meade.net
public void CommandBlind(string command, bool raw) public void CommandBlind(string command, bool raw)
{ {
LogMessage("CommandBlind", "raw: {0} command {0}", raw, command);
CheckConnected("CommandBlind"); CheckConnected("CommandBlind");
// Call CommandString and return as soon as it finishes // Call CommandString and return as soon as it finishes
//this.CommandString(command, raw); //this.CommandString(command, raw);
SharedResourcesWrapper.SendBlind(command); SharedResourcesWrapper.SendBlind(command, raw);
// or // or
//throw new ASCOM.MethodNotImplementedException("CommandBlind"); //throw new ASCOM.MethodNotImplementedException("CommandBlind");
// DO NOT have both these sections! One or the other // DO NOT have both these sections! One or the other
LogMessage("CommandBlind", "Completed");
} }
public bool CommandBool(string command, bool raw) public bool CommandBool(string command, bool raw)
{ {
LogMessage("CommandBool", "raw: {0} command {0}", raw, command);
CheckConnected("CommandBool"); CheckConnected("CommandBool");
//string ret = CommandString(command, raw); var result = SharedResourcesWrapper.SendBool(command, raw);
// decode the return string and return true or false LogMessage("CommandBool", "Completed: {0}", result);
return result;
// or // or
throw new MethodNotImplementedException("CommandBool"); //throw new MethodNotImplementedException("CommandBool");
// DO NOT have both these sections! One or the other // DO NOT have both these sections! One or the other
} }
public string CommandString(string command, bool raw) public string CommandString(string command, bool raw)
{ {
LogMessage("CommandString", "raw: {0} command {0}", raw, command);
CheckConnected("CommandString"); CheckConnected("CommandString");
// it's a good idea to put all the low level communication with the device here, // it's a good idea to put all the low level communication with the device here,
// then all communication calls this function // then all communication calls this function
// you need something to ensure that only one command is in progress at a time // you need something to ensure that only one command is in progress at a time
return SharedResourcesWrapper.SendString(command); var result = SharedResourcesWrapper.SendString(command, raw);
LogMessage("CommandBool", "Completed: {0}", result);
return result;
//throw new ASCOM.MethodNotImplementedException("CommandString"); //throw new ASCOM.MethodNotImplementedException("CommandString");
} }
@@ -225,7 +232,7 @@ namespace ASCOM.Meade.net
//todo fix this issue: A single halt command is sometimes missed by the #909 apm, so let's do it a few times to be safe. //todo fix this issue: A single halt command is sometimes missed by the #909 apm, so let's do it a few times to be safe.
SharedResourcesWrapper.SendBlind(":FQ#"); SharedResourcesWrapper.SendBlind("FQ");
//:FQ# Halt Focuser Motion //:FQ# Halt Focuser Motion
//Returns: Nothing //Returns: Nothing
} }
@@ -329,16 +336,16 @@ namespace ASCOM.Meade.net
private void MoveFocuser(bool directionOut, int steps) private void MoveFocuser(bool directionOut, int steps)
{ {
//_sharedResourcesWrapper.SendBlind(":FF#"); //_sharedResourcesWrapper.SendBlind("FF");
//:FF# Set Focus speed to fastest setting //:FF# Set Focus speed to fastest setting
//Returns: Nothing //Returns: Nothing
//:FS# Set Focus speed to slowest setting //:FS# Set Focus speed to slowest setting
//Returns: Nothing //Returns: Nothing
//:F<n># Autostar, Autostar II set focuser speed to <n> where <n> is an ASCII digit 1..4 //:F<n># Autostar, Autostar II - set focuser speed to <n> where <n> is an ASCII digit 1..4
//Returns: Nothing //Returns: Nothing
//All others Not Supported //All others - Not Supported
_utilities.WaitForMilliseconds(100); _utilities.WaitForMilliseconds(100);
PerformFocuserMove(directionOut); PerformFocuserMove(directionOut);
@@ -350,7 +357,7 @@ namespace ASCOM.Meade.net
private void PerformFocuserMove(bool directionOut) private void PerformFocuserMove(bool directionOut)
{ {
SharedResourcesWrapper.SendBlind(directionOut ? ":F+#" : ":F-#"); SharedResourcesWrapper.SendBlind(directionOut ? "F+" : "F-");
//:F+# Start Focuser moving inward (toward objective) //:F+# Start Focuser moving inward (toward objective)
//Returns: None //Returns: None
+2
View File
@@ -141,10 +141,12 @@
<Compile Include="LocalServer.cs" /> <Compile Include="LocalServer.cs" />
<Compile Include="MeadeTelescopeBase.cs" /> <Compile Include="MeadeTelescopeBase.cs" />
<Compile Include="ParkedBehaviour.cs" /> <Compile Include="ParkedBehaviour.cs" />
<Compile Include="ParkedPosition.cs" />
<Compile Include="ProfileFactory.cs" /> <Compile Include="ProfileFactory.cs" />
<Compile Include="ProfileProperties.cs" /> <Compile Include="ProfileProperties.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TelescopeList.cs" /> <Compile Include="TelescopeList.cs" />
<Compile Include="ThreadSafeValue.cs" />
<Compile Include="Win32Utilities.cs" /> <Compile Include="Win32Utilities.cs" />
<Compile Include="Wrapper\IProfileWrapper.cs" /> <Compile Include="Wrapper\IProfileWrapper.cs" />
<Compile Include="Wrapper\SharedResourcesWrapper.cs" /> <Compile Include="Wrapper\SharedResourcesWrapper.cs" />
+10
View File
@@ -0,0 +1,10 @@
namespace ASCOM.Meade.net
{
public class ParkedPosition
{
public double Altitude { get; set; }
public double Azimuth { get; set; }
public double RightAscension { get; set; }
public double Declination { get; set; }
}
}
+106 -10
View File
@@ -18,7 +18,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using ASCOM.DeviceInterface;
using ASCOM.Meade.net.Wrapper; using ASCOM.Meade.net.Wrapper;
using ASCOM.Utilities; using ASCOM.Utilities;
using ASCOM.Utilities.Interfaces; using ASCOM.Utilities.Interfaces;
@@ -77,12 +80,13 @@ namespace ASCOM.Meade.net
} }
//todo add code to ensure that there is a minimum gap between commands. 5ms as default. //todo add code to ensure that there is a minimum gap between commands. 5ms as default.
public static void SendBlind(string message) public static void SendBlind(string message, bool raw = false)
{ {
lock (LockObject) lock (LockObject)
{ {
SharedSerial.ClearBuffers(); SharedSerial.ClearBuffers();
SharedSerial.Transmit(message); var encodedMessage = raw ? message : $"#:{message}#";
SharedSerial.Transmit(encodedMessage);
} }
} }
@@ -93,14 +97,16 @@ namespace ASCOM.Meade.net
/// and that the reply will always be terminated by a "#" character. /// and that the reply will always be terminated by a "#" character.
/// </summary> /// </summary>
/// <param name="message"></param> /// <param name="message"></param>
/// <param name="raw"></param>
/// <returns></returns> /// <returns></returns>
public static string SendString(string message, bool includePrefix = true) public static string SendString(string message, bool raw = false)
{ {
lock (LockObject) lock (LockObject)
{ {
SharedSerial.ClearBuffers(); SharedSerial.ClearBuffers();
SharedSerial.Transmit(includePrefix ? $"#{message}" : message); var encodedMessage = raw ? message : $"#:{message}#";
SharedSerial.Transmit(encodedMessage);
try try
{ {
@@ -116,12 +122,22 @@ namespace ASCOM.Meade.net
} }
} }
public static string SendChar(string message) public static bool SendBool(string command, bool raw = false)
{
var result = SendChar(command, raw);
return result == "1";
}
public static string SendChar(string command, bool raw = false)
{ {
lock (LockObject) lock (LockObject)
{ {
SharedSerial.ClearBuffers(); SharedSerial.ClearBuffers();
SharedSerial.Transmit(message);
var encodedMessage = raw ? command : $"#:{command}#";
SharedSerial.Transmit(encodedMessage);
try try
{ {
@@ -230,7 +246,7 @@ namespace ASCOM.Meade.net
private const string HandShakeDefault = "None"; private const string HandShakeDefault = "None";
private const string ParityDefault = "None"; private const string ParityDefault = "None";
private const string SendDateTimeDefault = "false"; private const string SendDateTimeDefault = "false";
private static string ParkedBehaviourDefault = "No Coordinates"; private const string ParkedBehaviourDefault = "No Coordinates";
private const string ParkedAltDefault = "0"; private const string ParkedAltDefault = "0";
private const string ParkedAzimuthDefault = "180"; private const string ParkedAzimuthDefault = "180";
@@ -357,8 +373,8 @@ namespace ASCOM.Meade.net
try try
{ {
ProductName = SendString(":GVP#"); ProductName = SendString("GVP");
FirmwareVersion = SendString(":GVN#"); FirmwareVersion = SendString("GVN");
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -378,7 +394,7 @@ namespace ASCOM.Meade.net
try try
{ {
string utcOffSet = SendString(":GG#"); string utcOffSet = SendString("GG");
//:GG# Get UTC offset time //:GG# Get UTC offset time
//Returns: sHH# or sHH.H# //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 //The number of decimal hours to add to local time to convert it to UTC. If the number is a whole number the
@@ -479,5 +495,85 @@ namespace ASCOM.Meade.net
Count = 0; Count = 0;
} }
} }
public static void SetParked(bool atPark, ParkedPosition parkedPosition)
{
IsParked = atPark;
ParkedPosition = parkedPosition;
}
private static readonly ThreadSafeValue<bool> _isParked = false;
public static bool IsParked
{
get => _isParked;
private set => _isParked.Set(value);
}
private static ParkedPosition _parkedPosition;
public static ParkedPosition ParkedPosition
{
get => _parkedPosition;
private set => Interlocked.Exchange(ref _parkedPosition, value);
}
private static readonly ThreadSafeValue<PierSide> _sideOfPier = PierSide.pierUnknown;
/// <summary>
/// Start with <see cref="PierSide.pierUnknown"/>.
/// As we do not know the physical declination axis position, we have to keep track manually.
/// </summary>
public static PierSide SideOfPier
{
get => _sideOfPier;
internal set => _sideOfPier.Set(value);
}
private static readonly ThreadSafeValue<double?> _targetRightAscension = null as double?;
public static double? TargetRightAscension
{
get => _targetRightAscension;
internal set => _targetRightAscension.Set(value);
}
private static readonly ThreadSafeValue<double?> _targetDeclination = null as double?;
public static double? TargetDeclination
{
get => _targetDeclination;
internal set => _targetDeclination.Set(value);
}
private static int _slewSettleTime;
public static short SlewSettleTime
{
get => Convert.ToInt16(_slewSettleTime);
internal set => Interlocked.Exchange(ref _slewSettleTime, value);
}
private static readonly ThreadSafeValue<bool> _isLongFormat = false;
public static bool IsLongFormat
{
get => _isLongFormat;
internal set => _isLongFormat.Set(value);
}
private static readonly ThreadSafeValue<bool> _movingPrimary = false;
public static bool MovingPrimary
{
get => _movingPrimary;
internal set => _movingPrimary.Set(value);
}
private static readonly ThreadSafeValue<bool> _movingSecondary = false;
public static bool MovingSecondary
{
get => _movingSecondary;
internal set => _movingSecondary.Set(value);
}
private static readonly ThreadSafeValue<DateTime> _earliestNonSlewingTime = DateTime.MinValue;
public static DateTime EarliestNonSlewingTime
{
get => _earliestNonSlewingTime;
internal set => _earliestNonSlewingTime.Set(value);
}
} }
} }
+18
View File
@@ -0,0 +1,18 @@
using JetBrains.Annotations;
using System.Threading;
namespace ASCOM.Meade.net
{
public class ThreadSafeValue<T>
{
private object _value;
public ThreadSafeValue(in T value) => _value = value;
public void Set(in T value) => Interlocked.Exchange(ref _value, value);
public static implicit operator ThreadSafeValue<T>(in T value) => new ThreadSafeValue<T>(value);
public static implicit operator T([NotNull] ThreadSafeValue<T> @this) => (T)(@this?._value ?? default);
}
}
+91 -9
View File
@@ -1,4 +1,5 @@
using System; using System;
using ASCOM.DeviceInterface;
using ASCOM.Utilities.Interfaces; using ASCOM.Utilities.Interfaces;
namespace ASCOM.Meade.net.Wrapper namespace ASCOM.Meade.net.Wrapper
@@ -15,9 +16,10 @@ namespace ASCOM.Meade.net.Wrapper
void Lock(Action action); void Lock(Action action);
T Lock<T>(Func<T> func); T Lock<T>(Func<T> func);
string SendString(string message, bool includePrefix = true); string SendString(string message, bool raw = false);
void SendBlind(string message); void SendBlind(string message, bool raw = false);
string SendChar(string message); bool SendBool(string command, bool raw = false);
string SendChar(string message, bool raw = false);
string ReadTerminated(); string ReadTerminated();
@@ -26,6 +28,24 @@ namespace ASCOM.Meade.net.Wrapper
void SetupDialog(); void SetupDialog();
void WriteProfile(ProfileProperties profileProperties); void WriteProfile(ProfileProperties profileProperties);
void ReadCharacters(int throwAwayCharacters); void ReadCharacters(int throwAwayCharacters);
void SetParked(bool atPark, ParkedPosition parkedPosition);
bool IsParked { get; }
ParkedPosition ParkedPosition { get; }
PierSide SideOfPier { get; set; }
double? TargetRightAscension { get; set; }
double? TargetDeclination { get; set; }
short SlewSettleTime { get; set; }
bool IsLongFormat { get; set; }
bool MovingPrimary { get; set; }
bool MovingSecondary { get; set; }
DateTime EarliestNonSlewingTime { get; set; }
} }
public class SharedResourcesWrapper : ISharedResourcesWrapper public class SharedResourcesWrapper : ISharedResourcesWrapper
@@ -54,19 +74,24 @@ namespace ASCOM.Meade.net.Wrapper
return SharedResources.Lock(func); return SharedResources.Lock(func);
} }
public string SendString(string message, bool includePrefix = true) public string SendString(string message, bool raw = false)
{ {
return SharedResources.SendString(message, includePrefix); return SharedResources.SendString(message, raw);
} }
public void SendBlind(string message) public void SendBlind(string message, bool raw = false)
{ {
SharedResources.SendBlind(message); SharedResources.SendBlind(message, raw);
} }
public string SendChar(string message) public bool SendBool(string command, bool raw = false)
{ {
return SharedResources.SendChar(message); return SharedResources.SendBool(command, raw);
}
public string SendChar(string message, bool raw = false)
{
return SharedResources.SendChar(message, raw);
} }
public string ReadTerminated() public string ReadTerminated()
@@ -93,5 +118,62 @@ namespace ASCOM.Meade.net.Wrapper
{ {
SharedResources.WriteProfile(profileProperties); SharedResources.WriteProfile(profileProperties);
} }
public void SetParked(bool atPark, ParkedPosition parkedPosition)
{
SharedResources.SetParked(atPark, parkedPosition);
}
public bool IsParked => SharedResources.IsParked;
public ParkedPosition ParkedPosition => SharedResources.ParkedPosition;
public PierSide SideOfPier
{
get => SharedResources.SideOfPier;
set => SharedResources.SideOfPier = value;
}
public double? TargetRightAscension
{
get => SharedResources.TargetRightAscension;
set => SharedResources.TargetRightAscension = value;
}
public double? TargetDeclination
{
get => SharedResources.TargetDeclination;
set => SharedResources.TargetDeclination = value;
}
public short SlewSettleTime
{
get => SharedResources.SlewSettleTime;
set => SharedResources.SlewSettleTime = value;
}
public bool IsLongFormat
{
get => SharedResources.IsLongFormat;
set => SharedResources.IsLongFormat = value;
}
public bool MovingPrimary
{
get => SharedResources.MovingPrimary;
set => SharedResources.MovingPrimary = value;
}
public bool MovingSecondary
{
get => SharedResources.MovingSecondary;
set => SharedResources.MovingSecondary = value;
}
public DateTime EarliestNonSlewingTime
{
get => SharedResources.EarliestNonSlewingTime;
set => SharedResources.EarliestNonSlewingTime = value;
}
} }
} }