58ba1e6ee3
Release 0.5.0.0
* Removed unwanted files
* Adding git ignore file
* Started working on getting the basic communications with the scope working.
Working on routines to get and set the date and time in the handbox.
* Switched the serial port over to using the .net frameworks serial port.
Extracted the serial port into it's own class and created a simpler command processing mechanism.
* Implemented AbortSlew and did some code tidy up.
* Forced all code to 64-bit only, will make this 32/64 bit before release.
Fixed issue in the SerialProcessor when setting the time, makes sure that there's no chance of thread stealing when pulling out the junk messages
Added ConformanceResult.txt to show the progress of the driver development
* Added code for the site latitude
and started work on the longitude.
* Added unit tests for reading and writing the utcDate.
Fixed a couple of defects in the code that was setting the utcDate.
* Corrected Longitude value range
* Added support for UTC offset.
* Pulse guiding support added
* Added SiteLatitude unit tests
* Added unit tests for SiteLongitude
* Added unit tests for the new Pulse guide implementation.
* Added support for AlignmentMode
* Added support for AtPark and Park
* Added support for parking the scope
Added support for reading the scope Azimuth
* Added support for reading Declination
* Added 5 second timeout for the serial port.
Fixed problem with the GW command not working on the Autostar 497.
* Fixed broken unit test
* Added support for altitude
* Tidying up resharper warinings
* Implemented RightAscension
TargetRightAscension
TargetDec
SlewToCoord
and SlewToCoordAsync
* Sorted out the target RA and Dec exceptions to be compliant with ascom.
* Implemented SlewToAltAz and SlewToAltAzAsync
* Implemented SyncToTarget functionality
* Implemented slew to target
* Added support for MoveAxis
* Added support for tracking rate
* Added IFocuserV3 to the driver and made sure that it's registered for ASCOM as a focuser as well.
* Fixed issue with Target RA and Dec loosing precision
* Telescope driver now passes the Ascom conformance.
* Upgraded driver version to 0.1
* Added explicit locks around all sequences of commands.
* Basic implementation of the IFocusserV3
* Focuser passes validation, this makes the code V0.2
* Added support for CommandBlind and CommandString
Modified the tracking rates to be setable. However, the get is now simulated.
* Merged in feature/LocalServer (pull request #5)
Feature/LocalServer
* Major refactor. Switching over to a local server hub style driver allowing multiple programs to control the telescope at one time without the need for the POTH Hub
* Unified the setup dialog
* Implemented shared serial port, Both Telescope and Driver can connect at the same time.
* Ported the focuser implementation from the non server based version.
* Ported the telescope driver code.
* Fixed problem with # not being stripped from the returned string ends. Fixed issue with RA being returned as degress rather than hours.
* Telescope passes validation
* Added a lock around the focuser move.
* Reimplemented CommandBlind and CommandString
* Corrected version information
* Removed the Altitude support as there's a bug in the Autostar and Audiostar firmware
* Added comments for all meade commands.
Fixed the Site Lat and Long setters
* Re instated the Altitude value and ran conformance for both the telescope and focuser.
* Redesigned the Altitude and Azimuth readings to use the Right Ascension and Declination co-ordinates and perform the transformation using the date and site details from the scope. This will correct the problem of the Altitude reading from the handset being incorrect.
* Added code to make sure that the scope returns values in high precision mode.
* Fixed problem where SlewToAltAz didn't work correctly. Now uses the RA/Dec slew for everything, and converts the values as needed.
* Upgraded the error handling to ensure that all serial commands are executed after checking that there is a connection open.
* Added some code to the focuser connect to make it consistent with the telescope connect in that it will now test that the connection is to an Autostar.
Upgraded the move code to make it less unreliable.
* Added localisation support
* First draft of the installer
* Sorted out the registry settings needed to get the driver working properly on install.
* Modified the solution to be able to create as 32-bit install that works on 64bit windows 10.
* Added a call to activate when the setup dialog is shown.
380 lines
14 KiB
C#
380 lines
14 KiB
C#
//
|
|
// ================
|
|
// Shared Resources
|
|
// ================
|
|
//
|
|
// This class is a container for all shared resources that may be needed
|
|
// by the drivers served by the Local Server.
|
|
//
|
|
// NOTES:
|
|
//
|
|
// * ALL DECLARATIONS MUST BE STATIC HERE!! INSTANCES OF THIS CLASS MUST NEVER BE CREATED!
|
|
//
|
|
// Written by: Bob Denny 29-May-2007
|
|
// Modified by Chris Rowland and Peter Simpson to hamdle multiple hardware devices March 2011
|
|
//
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using ASCOM;
|
|
using ASCOM.Utilities;
|
|
|
|
namespace ASCOM.Meade.net
|
|
{
|
|
public class ProfileProperties
|
|
{
|
|
// properies that are part of the profile
|
|
public string ComPort { get; set; }
|
|
public bool TraceLogger { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// The resources shared by all drivers and devices, in this example it's a serial port with a shared SendMessage method
|
|
/// an idea for locking the message and handling connecting is given.
|
|
/// In reality extensive changes will probably be needed.
|
|
/// Multiple drivers means that several applications connect to the same hardware device, aka a hub.
|
|
/// Multiple devices means that there are more than one instance of the hardware, such as two focusers.
|
|
/// In this case there needs to be multiple instances of the hardware connector, each with it's own connection count.
|
|
/// </summary>
|
|
public static class SharedResources
|
|
{
|
|
// object used for locking to prevent multiple drivers accessing common code at the same time
|
|
private static readonly object lockObject = new object();
|
|
|
|
// Shared serial port. This will allow multiple drivers to use one single serial port.
|
|
private static ASCOM.Utilities.Serial s_sharedSerial; // Shared serial port
|
|
|
|
//
|
|
// Public access to shared resources
|
|
//
|
|
|
|
#region single serial port connector
|
|
|
|
//
|
|
// this region shows a way that a single serial port could be connected to by multiple
|
|
// drivers.
|
|
//
|
|
// Connected is used to handle the connections to the port.
|
|
//
|
|
// SendMessage is a way that messages could be sent to the hardware without
|
|
// conflicts between different drivers.
|
|
//
|
|
// All this is for a single connection, multiple connections would need multiple ports
|
|
// and a way to handle connecting and disconnection from them - see the
|
|
// multi driver handling section for ideas.
|
|
//
|
|
|
|
/// <summary>
|
|
/// Shared serial port
|
|
/// </summary>
|
|
public static ASCOM.Utilities.Serial SharedSerial => s_sharedSerial ?? (s_sharedSerial = new ASCOM.Utilities.Serial());
|
|
|
|
/// <summary>
|
|
/// number of connections to the shared serial port
|
|
/// </summary>
|
|
public static int Connections { get; set; } = 0;
|
|
|
|
public static void SendBlind(string message)
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
SharedSerial.ClearBuffers();
|
|
SharedSerial.Transmit(message);
|
|
}
|
|
}
|
|
|
|
public static bool SendBool(string message)
|
|
{
|
|
SharedSerial.ClearBuffers();
|
|
return SendChar(message) == "1";
|
|
}
|
|
|
|
/// <summary>
|
|
/// Example of a shared SendMessage method, the lock
|
|
/// prevents different drivers tripping over one another.
|
|
/// It needs error handling and assumes that the message will be sent unchanged
|
|
/// and that the reply will always be terminated by a "#" character.
|
|
/// </summary>
|
|
/// <param name="message"></param>
|
|
/// <returns></returns>
|
|
public static string SendString(string message)
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
SharedSerial.ClearBuffers();
|
|
SharedSerial.Transmit(message);
|
|
return SharedSerial.ReceiveTerminated("#").TrimEnd('#');
|
|
}
|
|
}
|
|
|
|
public static string SendChar(string message)
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
SharedSerial.ClearBuffers();
|
|
SharedSerial.Transmit(message);
|
|
return SharedSerial.ReceiveCounted(1);
|
|
}
|
|
}
|
|
|
|
public static string ReadTerminated()
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
return SharedSerial.ReceiveTerminated("#");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Example of handling connecting to and disconnection from the
|
|
/// shared serial port.
|
|
/// Needs error handling
|
|
/// the port name etc. needs to be set up first, this could be done by the driver
|
|
/// checking Connected and if it's false setting up the port before setting connected to true.
|
|
/// It could also be put here.
|
|
/// </summary>
|
|
public static bool Connected
|
|
{
|
|
set
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
if (value)
|
|
{
|
|
if (Connections == 0)
|
|
SharedSerial.Connected = true;
|
|
Connections++;
|
|
}
|
|
else
|
|
{
|
|
Connections--;
|
|
if (Connections <= 0)
|
|
{
|
|
SharedSerial.Connected = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
get { return SharedSerial.Connected; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Profile
|
|
|
|
internal static string driverID = "ASCOM.MeadeGeneric.Telescope";
|
|
|
|
// Constants used for Profile persistence
|
|
internal static string comPortProfileName = "COM Port";
|
|
internal static string traceStateProfileName = "Trace Level";
|
|
|
|
public static void WriteProfile(ProfileProperties profileProperties)
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
using (Profile driverProfile = new Profile())
|
|
{
|
|
driverProfile.DeviceType = "Telescope";
|
|
driverProfile.WriteValue(driverID, traceStateProfileName, profileProperties.TraceLogger.ToString());
|
|
driverProfile.WriteValue(driverID, comPortProfileName, profileProperties.ComPort);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static readonly string comPortDefault = "COM1";
|
|
internal static string traceStateDefault = "false";
|
|
|
|
public static ProfileProperties ReadProfile()
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
ProfileProperties profileProperties = new ProfileProperties();
|
|
using (Profile driverProfile = new Profile())
|
|
{
|
|
driverProfile.DeviceType = "Telescope";
|
|
profileProperties.ComPort =
|
|
driverProfile.GetValue(driverID, comPortProfileName, string.Empty, comPortDefault);
|
|
profileProperties.TraceLogger = Convert.ToBoolean(driverProfile.GetValue(driverID,
|
|
traceStateProfileName, string.Empty, traceStateDefault));
|
|
}
|
|
|
|
return profileProperties;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region SetupDialog
|
|
|
|
public static void SetupDialog()
|
|
{
|
|
// consider only showing the setup dialog if not connected
|
|
// or call a different dialog if connected
|
|
if (Connections > 0)
|
|
{
|
|
System.Windows.Forms.MessageBox.Show("Already connected, please disconnect before altering settings");
|
|
return;
|
|
}
|
|
|
|
var profileProperties = ReadProfile();
|
|
|
|
using (SetupDialogForm F = new SetupDialogForm())
|
|
{
|
|
F.SetProfile(profileProperties);
|
|
|
|
var result = F.ShowDialog();
|
|
if (result == System.Windows.Forms.DialogResult.OK)
|
|
{
|
|
profileProperties = F.GetProfile();
|
|
|
|
WriteProfile(profileProperties); // Persist device configuration values to the ASCOM Profile store
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Multi Driver handling
|
|
|
|
// this section illustrates how multiple drivers could be handled,
|
|
// it's for drivers where multiple connections to the hardware can be made and ensures that the
|
|
// hardware is only disconnected from when all the connected devices have disconnected.
|
|
|
|
// It is NOT a complete solution! This is to give ideas of what can - or should be done.
|
|
//
|
|
// An alternative would be to move the hardware control here, handle connecting and disconnecting,
|
|
// and provide the device with a suitable connection to the hardware.
|
|
//
|
|
/// <summary>
|
|
/// dictionary carrying device connections.
|
|
/// The Key is the connection number that identifies the device, it could be the COM port name,
|
|
/// USB ID or IP Address, the Value is the DeviceHardware class
|
|
/// </summary>
|
|
private static Dictionary<string, DeviceHardware> connectedDevices = new Dictionary<string, DeviceHardware>();
|
|
|
|
/// <summary>
|
|
/// This is called in the driver Connect(true) property,
|
|
/// it add the device id to the list of devices if it's not there and increments the device count.
|
|
/// </summary>
|
|
/// <param name="deviceId"></param>
|
|
public static void Connect(string deviceId)
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
if (!connectedDevices.ContainsKey(deviceId))
|
|
connectedDevices.Add(deviceId, new DeviceHardware());
|
|
connectedDevices[deviceId].count++; // increment the value
|
|
|
|
if (deviceId == "Serial")
|
|
{
|
|
if (connectedDevices[deviceId].count == 1)
|
|
{
|
|
var profileProperties = ReadProfile();
|
|
SharedResources.SharedSerial.PortName = profileProperties.ComPort;
|
|
SharedResources.SharedSerial.DTREnable = false;
|
|
SharedResources.SharedSerial.RTSEnable = false;
|
|
SharedResources.SharedSerial.DataBits = 8;
|
|
SharedResources.SharedSerial.StopBits = SerialStopBits.One;
|
|
SharedResources.SharedSerial.Parity = SerialParity.None;
|
|
SharedResources.SharedSerial.Speed = SerialSpeed.ps9600;
|
|
SharedResources.SharedSerial.Handshake = SerialHandshake.None;
|
|
SharedResources.SharedSerial.Connected = true;
|
|
|
|
string firmware = SendString(":GVN#");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void Disconnect(string deviceId)
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
if (connectedDevices.ContainsKey(deviceId))
|
|
{
|
|
connectedDevices[deviceId].count--;
|
|
if (connectedDevices[deviceId].count <= 0)
|
|
{
|
|
connectedDevices.Remove(deviceId);
|
|
if (deviceId == "Serial")
|
|
{
|
|
SharedResources.SharedSerial.Connected = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool IsConnected(string deviceId)
|
|
{
|
|
if (connectedDevices.ContainsKey(deviceId))
|
|
return (connectedDevices[deviceId].count > 0);
|
|
else
|
|
return false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
public static void Lock(Action action)
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
action();
|
|
}
|
|
}
|
|
|
|
public static T Lock<T>(Func<T> func)
|
|
{
|
|
lock (lockObject)
|
|
{
|
|
return func();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Skeleton of a hardware class, all this does is hold a count of the connections,
|
|
/// in reality extra code will be needed to handle the hardware in some way
|
|
/// </summary>
|
|
public class DeviceHardware
|
|
{
|
|
private int _count;
|
|
|
|
internal int count
|
|
{
|
|
set => _count = value;
|
|
get => _count;
|
|
}
|
|
|
|
internal DeviceHardware()
|
|
{
|
|
count = 0;
|
|
}
|
|
}
|
|
|
|
//#region ServedClassName attribute
|
|
///// <summary>
|
|
///// This is only needed if the driver is targeted at platform 5.5, it is included with Platform 6
|
|
///// </summary>
|
|
//[global::System.AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
|
//public sealed class ServedClassNameAttribute : Attribute
|
|
//{
|
|
// // See the attribute guidelines at
|
|
// // http://go.microsoft.com/fwlink/?LinkId=85236
|
|
|
|
// /// <summary>
|
|
// /// Gets or sets the 'friendly name' of the served class, as registered with the ASCOM Chooser.
|
|
// /// </summary>
|
|
// /// <value>The 'friendly name' of the served class.</value>
|
|
// public string DisplayName { get; private set; }
|
|
// /// <summary>
|
|
// /// Initializes a new instance of the <see cref="ServedClassNameAttribute"/> class.
|
|
// /// </summary>
|
|
// /// <param name="servedClassName">The 'friendly name' of the served class.</param>
|
|
// public ServedClassNameAttribute(string servedClassName)
|
|
// {
|
|
// DisplayName = servedClassName;
|
|
// }
|
|
//}
|
|
//#endregion
|
|
}
|
|
} |